From: patrick Date: Wed, 28 Apr 2021 12:28:50 +0000 (+0000) Subject: Import LLVM 11.1.0 release including clang, lld and lldb. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ec727ea710c91afd8ce4f788c5aaa8482b7b69b2;p=openbsd Import LLVM 11.1.0 release including clang, lld and lldb. --- diff --git a/gnu/llvm/clang/.clang-tidy b/gnu/llvm/clang/.clang-tidy index 849c26987ef..5b425a71202 100644 --- a/gnu/llvm/clang/.clang-tidy +++ b/gnu/llvm/clang/.clang-tidy @@ -19,4 +19,6 @@ CheckOptions: value: CamelCase - key: readability-identifier-naming.VariableCase value: CamelCase + - key: readability-identifier-naming.IgnoreMainLikeFunctions + value: 1 diff --git a/gnu/llvm/clang/CMakeLists.txt b/gnu/llvm/clang/CMakeLists.txt index dc1413f4b59..bb4b801f01c 100644 --- a/gnu/llvm/clang/CMakeLists.txt +++ b/gnu/llvm/clang/CMakeLists.txt @@ -9,6 +9,10 @@ endif() if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) project(Clang) + set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to") + set(CMAKE_CXX_STANDARD_REQUIRED YES) + set(CMAKE_CXX_EXTENSIONS NO) + # Rely on llvm-config. set(CONFIG_OUTPUT) if(LLVM_CONFIG) @@ -117,6 +121,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) include(LLVMDistributionSupport) set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}") + set(BUG_REPORT_URL "${LLVM_PACKAGE_BUGREPORT}" CACHE STRING + "Default URL where bug reports are to be submitted.") if (NOT DEFINED LLVM_INCLUDE_TESTS) set(LLVM_INCLUDE_TESTS ON) @@ -130,16 +136,38 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} ) if(LLVM_INCLUDE_TESTS) - include(FindPythonInterp) - if(NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR -"Unable to find Python interpreter, required for builds and testing. + if(CMAKE_VERSION VERSION_LESS 3.12) + include(FindPythonInterp) + if(NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR + "Unable to find Python interpreter, required for builds and testing. -Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") - endif() + Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") + endif() + + if( ${PYTHON_VERSION_STRING} VERSION_LESS 2.7 ) + message(FATAL_ERROR "Python 2.7 or newer is required") + endif() - if( ${PYTHON_VERSION_STRING} VERSION_LESS 2.7 ) - message(FATAL_ERROR "Python 2.7 or newer is required") + add_executable(Python3::Interpreter IMPORTED) + set_target_properties(Python3::Interpreter PROPERTIES + IMPORTED_LOCATION ${PYTHON_EXECUTABLE}) + set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) + else() + find_package(Python3 COMPONENTS Interpreter) + if(NOT Python3_Interpreter_FOUND) + message(WARNING "Python3 not found, using python2 as a fallback") + find_package(Python2 COMPONENTS Interpreter REQUIRED) + if(Python2_VERSION VERSION_LESS 2.7) + message(SEND_ERROR "Python 2.7 or newer is required") + endif() + + # Treat python2 as python3 + add_executable(Python3::Interpreter IMPORTED) + set_target_properties(Python3::Interpreter PROPERTIES + IMPORTED_LOCATION ${Python2_EXECUTABLE}) + set(Python3_EXECUTABLE ${Python2_EXECUTABLE}) + endif() endif() # Check prebuilt llvm/utils. @@ -226,7 +254,7 @@ set(C_INCLUDE_DIRS "" CACHE STRING "Colon separated list of directories clang will search for headers.") set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." ) -set(DEFAULT_SYSROOT "" CACHE PATH +set(DEFAULT_SYSROOT "" CACHE STRING "Default to all compiler invocations for --sysroot=." ) set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld") @@ -306,6 +334,8 @@ if (NOT DEFINED MATCHED_ARCH OR "${CMAKE_MATCH_1}" LESS 35) "Default architecture for OpenMP offloading to Nvidia GPUs." FORCE) endif() +set(CLANG_SYSTEMZ_DEFAULT_ARCH "z10" CACHE STRING "SystemZ Default Arch") + set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING "Vendor-specific text for showing with version information.") @@ -479,7 +509,7 @@ set(CLANG_EXECUTABLE_VERSION "${CLANG_VERSION_MAJOR}" CACHE STRING "Major version number that will be appended to the clang executable name") set(LIBCLANG_LIBRARY_VERSION - "${CLANG_VERSION_MAJOR}" CACHE STRING + "${CLANG_VERSION_MAJOR}.${CLANG_VERSION_MINOR}" CACHE STRING "Major version number that will be appended to the libclang library") mark_as_advanced(CLANG_EXECUTABLE_VERSION LIBCLANG_LIBRARY_VERSION) @@ -493,7 +523,10 @@ add_subdirectory(include) # All targets below may depend on all tablegen'd files. get_property(CLANG_TABLEGEN_TARGETS GLOBAL PROPERTY CLANG_TABLEGEN_TARGETS) -add_custom_target(clang-tablegen-targets DEPENDS ${CLANG_TABLEGEN_TARGETS}) +add_custom_target(clang-tablegen-targets + DEPENDS + omp_gen + ${CLANG_TABLEGEN_TARGETS}) set_target_properties(clang-tablegen-targets PROPERTIES FOLDER "Misc") list(APPEND LLVM_COMMON_DEPENDS clang-tablegen-targets) @@ -588,6 +621,7 @@ if(CLANG_LIBS) add_dependencies(clang-libraries ${lib}) if(NOT LLVM_ENABLE_IDE) add_dependencies(install-clang-libraries install-${lib}) + add_dependencies(install-clang-libraries-stripped install-${lib}-stripped) endif() endforeach() endif() @@ -686,6 +720,7 @@ if (CLANG_ENABLE_BOOTSTRAP) CLANG_VERSION_MAJOR CLANG_VERSION_MINOR CLANG_VERSION_PATCHLEVEL + CLANG_VENDOR LLVM_VERSION_SUFFIX LLVM_BINUTILS_INCDIR CLANG_REPOSITORY_STRING diff --git a/gnu/llvm/clang/bindings/python/clang/cindex.py b/gnu/llvm/clang/bindings/python/clang/cindex.py index 8e5a9fe0068..aceaa131f15 100644 --- a/gnu/llvm/clang/bindings/python/clang/cindex.py +++ b/gnu/llvm/clang/bindings/python/clang/cindex.py @@ -2122,6 +2122,7 @@ TypeKind.OCLQUEUE = TypeKind(159) TypeKind.OCLRESERVEID = TypeKind(160) TypeKind.EXTVECTOR = TypeKind(176) +TypeKind.ATOMIC = TypeKind(177) class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" diff --git a/gnu/llvm/clang/bindings/python/tests/CMakeLists.txt b/gnu/llvm/clang/bindings/python/tests/CMakeLists.txt index 626256af9c1..3f58c4bde8e 100644 --- a/gnu/llvm/clang/bindings/python/tests/CMakeLists.txt +++ b/gnu/llvm/clang/bindings/python/tests/CMakeLists.txt @@ -3,7 +3,7 @@ add_custom_target(check-clang-python COMMAND ${CMAKE_COMMAND} -E env CLANG_LIBRARY_PATH=$ - ${PYTHON_EXECUTABLE} -m unittest discover + "${Python3_EXECUTABLE}" -m unittest discover DEPENDS libclang WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..) diff --git a/gnu/llvm/clang/bindings/python/tests/cindex/test_diagnostics.py b/gnu/llvm/clang/bindings/python/tests/cindex/test_diagnostics.py index 52928db7303..64d0ca2ef9b 100644 --- a/gnu/llvm/clang/bindings/python/tests/cindex/test_diagnostics.py +++ b/gnu/llvm/clang/bindings/python/tests/cindex/test_diagnostics.py @@ -100,7 +100,7 @@ class TestDiagnostics(unittest.TestCase): self.assertRegexpMatches(children[0].spelling, '.*declared here') self.assertEqual(children[0].location.line, 1) - self.assertEqual(children[0].location.column, 1) + self.assertEqual(children[0].location.column, 6) def test_diagnostic_string_repr(self): tu = get_tu('struct MissingSemicolon{}') diff --git a/gnu/llvm/clang/cmake/caches/Apple-stage1.cmake b/gnu/llvm/clang/cmake/caches/Apple-stage1.cmake index 4b11342086a..8a4fe6dfdfd 100644 --- a/gnu/llvm/clang/cmake/caches/Apple-stage1.cmake +++ b/gnu/llvm/clang/cmake/caches/Apple-stage1.cmake @@ -20,6 +20,7 @@ set(CMAKE_MACOSX_RPATH ON CACHE BOOL "") set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") +set(CLANG_SPAWN_CC1 ON CACHE BOOL "") set(CLANG_BOOTSTRAP_PASSTHROUGH CMAKE_OSX_ARCHITECTURES CACHE STRING "") diff --git a/gnu/llvm/clang/cmake/caches/Apple-stage2.cmake b/gnu/llvm/clang/cmake/caches/Apple-stage2.cmake index eb482700201..b24ec558c07 100644 --- a/gnu/llvm/clang/cmake/caches/Apple-stage2.cmake +++ b/gnu/llvm/clang/cmake/caches/Apple-stage2.cmake @@ -16,6 +16,7 @@ set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(LLVM_ENABLE_MODULES ON CACHE BOOL "") set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") +set(CLANG_SPAWN_CC1 ON CACHE BOOL "") set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "") set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "Build Compiler-RT with just-built clang") diff --git a/gnu/llvm/clang/cmake/caches/CrossWinToARMLinux.cmake b/gnu/llvm/clang/cmake/caches/CrossWinToARMLinux.cmake index d08e09a291f..9aa0efa8049 100644 --- a/gnu/llvm/clang/cmake/caches/CrossWinToARMLinux.cmake +++ b/gnu/llvm/clang/cmake/caches/CrossWinToARMLinux.cmake @@ -25,6 +25,14 @@ # cmake --build . --target check-clang # cmake --build . --target check-lld +# LLVM_PROJECT_DIR is the path to the llvm-project directory. +# The right way to compute it would probably be to use "${CMAKE_SOURCE_DIR}/../", +# but CMAKE_SOURCE_DIR is set to the wrong value on earlier CMake versions +# that we still need to support (for instance, 3.10.2). +get_filename_component(LLVM_PROJECT_DIR + "${CMAKE_CURRENT_LIST_DIR}/../../../" + ABSOLUTE) + if (NOT DEFINED DEFAULT_SYSROOT) message(WARNING "DEFAULT_SYSROOT must be specified for the cross toolchain build.") endif() @@ -78,19 +86,26 @@ set(LIBCXXABI_TARGET_TRIPLE "${CMAKE_C_COMPILER_TARGET}" CACHE S set(LIBCXXABI_SYSROOT "${DEFAULT_SYSROOT}" CACHE STRING "") set(LIBCXXABI_LINK_TESTS_WITH_SHARED_LIBCXXABI OFF CACHE BOOL "") set(LIBCXXABI_LINK_TESTS_WITH_SHARED_LIBCXX OFF CACHE BOOL "") +set(LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXXABI OFF CACHE BOOL "") +set(LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXX OFF CACHE BOOL "") set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXX_TARGET_TRIPLE "${CMAKE_C_COMPILER_TARGET}" CACHE STRING "") set(LIBCXX_SYSROOT "${DEFAULT_SYSROOT}" CACHE STRING "") set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") +set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LLVM_PROJECT_DIR}/libcxxabi/include" CACHE PATH "") +set(LIBCXX_CXX_ABI_LIBRARY_PATH "${CMAKE_BINARY_DIR}/lib/${LIBCXX_TARGET_TRIPLE}/c++" CACHE PATH "") set(BUILTINS_CMAKE_ARGS "-DCMAKE_SYSTEM_NAME=Linux;-DCMAKE_AR=${CMAKE_AR}" CACHE STRING "") set(RUNTIMES_CMAKE_ARGS "-DCMAKE_SYSTEM_NAME=Linux;-DCMAKE_AR=${CMAKE_AR}" CACHE STRING "") +find_package(Python3 COMPONENTS Interpreter) + # Remote test configuration. if(DEFINED REMOTE_TEST_HOST) - set(DEFAULT_TEST_EXECUTOR "SSHExecutor('${REMOTE_TEST_HOST}', '${REMOTE_TEST_USER}')") - set(DEFAULT_TEST_TARGET_INFO "libcxx.test.target_info.LinuxLocalTI") + set(DEFAULT_TEST_EXECUTOR "\\\"${Python3_EXECUTABLE}\\\" \\\"${LLVM_PROJECT_DIR}/libcxx/utils/ssh.py\\\" --host='${REMOTE_TEST_USER}@${REMOTE_TEST_HOST}'") + set(DEFAULT_TEST_TARGET_INFO "libcxx.test.target_info.LinuxRemoteTI") # Allow override with the custom values. if(NOT DEFINED LIBUNWIND_TARGET_INFO) diff --git a/gnu/llvm/clang/cmake/caches/Fuchsia-stage2.cmake b/gnu/llvm/clang/cmake/caches/Fuchsia-stage2.cmake index b338f1b8a08..259684ff2b0 100644 --- a/gnu/llvm/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/gnu/llvm/clang/cmake/caches/Fuchsia-stage2.cmake @@ -4,6 +4,9 @@ set(LLVM_TARGETS_TO_BUILD X86;ARM;AArch64;RISCV CACHE STRING "") set(PACKAGE_VENDOR Fuchsia CACHE STRING "") +set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld;llvm" CACHE STRING "") +set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") + set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") if(NOT APPLE) set(LLVM_ENABLE_LLD ON CACHE BOOL "") @@ -16,7 +19,12 @@ set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") set(LLVM_INCLUDE_GO_TESTS OFF CACHE BOOL "") -set(LLVM_USE_RELATIVE_PATHS_IN_DEBUG_INFO ON CACHE BOOL "") +set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "") +set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") + +if(MSVC) + set(LLVM_USE_CRT_RELEASE "MT" CACHE STRING "") +endif() set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "") if(NOT APPLE) @@ -35,6 +43,8 @@ set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "") set(CMAKE_BUILD_TYPE Release CACHE STRING "") if (APPLE) set(MACOSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "") +elseif(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "") endif() if(APPLE) @@ -43,6 +53,7 @@ if(APPLE) set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "") set(COMPILER_RT_ENABLE_WATCHOS OFF CACHE BOOL "") + set(COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") set(LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") @@ -62,12 +73,34 @@ if(APPLE) set(SANITIZER_MIN_OSX_VERSION 10.7 CACHE STRING "") endif() +if(WIN32) + set(target "x86_64-pc-windows-msvc") + + list(APPEND BUILTIN_TARGETS "${target}") + set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Windows CACHE STRING "") + set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + + list(APPEND RUNTIME_TARGETS "${target}") + set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Windows CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}_LIBCXX_HAS_WIN32_THREAD_API ON CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx" CACHE STRING "") +endif() + foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unknown-linux-gnu;x86_64-unknown-linux-gnu) if(LINUX_${target}_SYSROOT) # Set the per-target builtins options. list(APPEND BUILTIN_TARGETS "${target}") set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + set(BUILTINS_${target}_CMAKE_C_FLAGS "--target=${target}" CACHE STRING "") + set(BUILTINS_${target}_CMAKE_CXX_FLAGS "--target=${target}" CACHE STRING "") + set(BUILTINS_${target}_CMAKE_ASM_FLAGS "--target=${target}" CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSROOT ${LINUX_${target}_SYSROOT} CACHE STRING "") set(BUILTINS_${target}_CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") set(BUILTINS_${target}_CMAKE_MODULE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") @@ -77,11 +110,14 @@ foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unkn list(APPEND RUNTIME_TARGETS "${target}") set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_C_FLAGS "--target=${target}" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_CXX_FLAGS "--target=${target}" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_ASM_FLAGS "--target=${target}" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SYSROOT ${LINUX_${target}_SYSROOT} CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_MODULE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") - set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") @@ -94,9 +130,10 @@ foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unkn set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI "libc++" CACHE STRING "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI_INTREE ON CACHE BOOL "") - set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") # Use .build-id link. list(APPEND RUNTIME_BUILD_ID_LINK "${target}") @@ -105,15 +142,16 @@ endforeach() if(FUCHSIA_SDK) set(FUCHSIA_aarch64_NAME arm64) + set(FUCHSIA_i386_NAME x64) set(FUCHSIA_x86_64_NAME x64) set(FUCHSIA_riscv64_NAME riscv64) - foreach(target x86_64;aarch64;riscv64) - set(FUCHSIA_${target}_COMPILER_FLAGS "-I${FUCHSIA_SDK}/pkg/fdio/include") + foreach(target i386;x86_64;aarch64;riscv64) + set(FUCHSIA_${target}_COMPILER_FLAGS "--target=${target}-unknown-fuchsia -I${FUCHSIA_SDK}/pkg/fdio/include") set(FUCHSIA_${target}_LINKER_FLAGS "-L${FUCHSIA_SDK}/arch/${FUCHSIA_${target}_NAME}/lib") set(FUCHSIA_${target}_SYSROOT "${FUCHSIA_SDK}/arch/${FUCHSIA_${target}_NAME}/sysroot") endforeach() - foreach(target x86_64;aarch64;riscv64) + foreach(target i386;x86_64;aarch64;riscv64) # Set the per-target builtins options. list(APPEND BUILTIN_TARGETS "${target}-unknown-fuchsia") set(BUILTINS_${target}-unknown-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "") @@ -140,7 +178,7 @@ if(FUCHSIA_SDK) set(RUNTIMES_${target}-unknown-fuchsia_CMAKE_MODULE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE STRING "") set(RUNTIMES_${target}-unknown-fuchsia_CMAKE_EXE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE STRING "") set(RUNTIMES_${target}-unknown-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") - set(RUNTIMES_${target}-unknown-fuchsia_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}-unknown-fuchsia_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBUNWIND_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBUNWIND_INSTALL_STATIC_LIBRARY OFF CACHE BOOL "") @@ -155,6 +193,8 @@ if(FUCHSIA_SDK) set(RUNTIMES_${target}-unknown-fuchsia_LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OFF CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}-unknown-fuchsia_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}-unknown-fuchsia_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") set(RUNTIMES_${target}-unknown-fuchsia+asan_LLVM_BUILD_COMPILER_RT OFF CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia+asan_LLVM_USE_SANITIZER "Address" CACHE STRING "") @@ -195,6 +235,7 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-cxxfilt llvm-dwarfdump llvm-dwp + llvm-gsymutil llvm-lib llvm-nm llvm-objcopy diff --git a/gnu/llvm/clang/cmake/caches/Fuchsia.cmake b/gnu/llvm/clang/cmake/caches/Fuchsia.cmake index 2a65de2039c..8688b71ecc7 100644 --- a/gnu/llvm/clang/cmake/caches/Fuchsia.cmake +++ b/gnu/llvm/clang/cmake/caches/Fuchsia.cmake @@ -4,6 +4,8 @@ set(LLVM_TARGETS_TO_BUILD X86;ARM;AArch64;RISCV CACHE STRING "") set(PACKAGE_VENDOR Fuchsia CACHE STRING "") +set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld;llvm" CACHE STRING "") + set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") @@ -13,6 +15,10 @@ set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") set(LLVM_INCLUDE_GO_TESTS OFF CACHE BOOL "") +if(MSVC) + set(LLVM_USE_CRT_RELEASE "MT" CACHE STRING "") +endif() + set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "") if(NOT APPLE) set(CLANG_DEFAULT_LINKER lld CACHE STRING "") @@ -29,8 +35,10 @@ set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "") set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(CMAKE_BUILD_TYPE Release CACHE STRING "") -if (APPLE) +if(APPLE) set(MACOSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "") +elseif(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "") endif() if(APPLE) @@ -49,20 +57,33 @@ set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") set(LIBCXX_ABI_VERSION 2 CACHE STRING "") set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") -set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") -set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +if(WIN32) + set(LIBCXX_HAS_WIN32_THREAD_API ON CACHE BOOL "") + set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") + set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") + set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") + set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY OFF CACHE BOOL "") + set(BUILTINS_CMAKE_ARGS -DCMAKE_SYSTEM_NAME=Windows CACHE STRING "") + set(RUNTIMES_CMAKE_ARGS -DCMAKE_SYSTEM_NAME=Windows CACHE STRING "") + set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx" CACHE STRING "") +else() + set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") + set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") +endif() if(BOOTSTRAP_CMAKE_SYSTEM_NAME) set(target "${BOOTSTRAP_CMAKE_CXX_COMPILER_TARGET}") if(STAGE2_LINUX_${target}_SYSROOT) + set(LLVM_BUILTIN_TARGETS "${target}" CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(BUILTINS_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSROOT ${STAGE2_LINUX_${target}_SYSROOT} CACHE STRING "") - set(LLVM_BUILTIN_TARGETS "${target}" CACHE STRING "") + set(LLVM_RUNTIME_TARGETS "${target}" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(RUNTIMES_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SYSROOT ${STAGE2_LINUX_${target}_SYSROOT} CACHE STRING "") + set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") @@ -76,10 +97,9 @@ if(BOOTSTRAP_CMAKE_SYSTEM_NAME) set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI "libc++" CACHE STRING "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI_INTREE ON CACHE BOOL "") - set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") - set(LLVM_RUNTIME_TARGETS "${target}" CACHE STRING "") endif() endif() diff --git a/gnu/llvm/clang/cmake/modules/AddClang.cmake b/gnu/llvm/clang/cmake/modules/AddClang.cmake index 577cc11ab01..704278a0e93 100644 --- a/gnu/llvm/clang/cmake/modules/AddClang.cmake +++ b/gnu/llvm/clang/cmake/modules/AddClang.cmake @@ -17,7 +17,7 @@ function(clang_tablegen) message(FATAL_ERROR "SOURCE source-file required by clang_tablegen") endif() - set( CLANG_TABLEGEN_ARGUMENTS -I ${CLANG_SOURCE_DIR}/include ) + set( CLANG_TABLEGEN_ARGUMENTS "" ) set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} ) tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS} ${CLANG_TABLEGEN_ARGUMENTS}) @@ -45,7 +45,7 @@ endmacro() macro(add_clang_library name) cmake_parse_arguments(ARG - "SHARED;INSTALL_WITH_TOOLCHAIN" + "SHARED;STATIC;INSTALL_WITH_TOOLCHAIN" "" "ADDITIONAL_HEADERS" ${ARGN}) @@ -81,7 +81,10 @@ macro(add_clang_library name) ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args. ) endif() - if(ARG_SHARED) + + if(ARG_SHARED AND ARG_STATIC) + set(LIBTYPE SHARED STATIC) + elseif(ARG_SHARED) set(LIBTYPE SHARED) else() # llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set, @@ -99,38 +102,45 @@ macro(add_clang_library name) endif() llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs}) - if(TARGET ${name}) - target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS}) - - if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN) - set(export_to_clangtargets) - if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - "clang-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_clangtargets EXPORT ClangTargets) - set_property(GLOBAL PROPERTY CLANG_HAS_EXPORTS True) - endif() + set(libs ${name}) + if(ARG_SHARED AND ARG_STATIC) + list(APPEND libs ${name}_static) + endif() - install(TARGETS ${name} - COMPONENT ${name} - ${export_to_clangtargets} - LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} - RUNTIME DESTINATION bin) - - if (NOT LLVM_ENABLE_IDE) - add_llvm_install_targets(install-${name} - DEPENDS ${name} - COMPONENT ${name}) + foreach(lib ${libs}) + if(TARGET ${lib}) + target_link_libraries(${lib} INTERFACE ${LLVM_COMMON_LIBS}) + + if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN) + set(export_to_clangtargets) + if(${lib} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR + "clang-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR + NOT LLVM_DISTRIBUTION_COMPONENTS) + set(export_to_clangtargets EXPORT ClangTargets) + set_property(GLOBAL PROPERTY CLANG_HAS_EXPORTS True) + endif() + + install(TARGETS ${lib} + COMPONENT ${lib} + ${export_to_clangtargets} + LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} + RUNTIME DESTINATION bin) + + if (NOT LLVM_ENABLE_IDE) + add_llvm_install_targets(install-${lib} + DEPENDS ${lib} + COMPONENT ${lib}) + endif() + + set_property(GLOBAL APPEND PROPERTY CLANG_LIBS ${lib}) endif() - - set_property(GLOBAL APPEND PROPERTY CLANG_LIBS ${name}) + set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${lib}) + else() + # Add empty "phony" target + add_custom_target(${lib}) endif() - set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) - else() - # Add empty "phony" target - add_custom_target(${name}) - endif() + endforeach() set_target_properties(${name} PROPERTIES FOLDER "Clang libraries") set_clang_windows_version_resource_properties(${name}) diff --git a/gnu/llvm/clang/cmake/modules/ClangConfig.cmake.in b/gnu/llvm/clang/cmake/modules/ClangConfig.cmake.in index a5a7eae5032..c5ce56274b1 100644 --- a/gnu/llvm/clang/cmake/modules/ClangConfig.cmake.in +++ b/gnu/llvm/clang/cmake/modules/ClangConfig.cmake.in @@ -8,6 +8,7 @@ find_package(LLVM REQUIRED CONFIG set(CLANG_EXPORTED_TARGETS "@CLANG_EXPORTS@") set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@") set(CLANG_INCLUDE_DIRS "@CLANG_CONFIG_INCLUDE_DIRS@") +set(CLANG_LINK_CLANG_DYLIB "@CLANG_LINK_CLANG_DYLIB@") # Provide all our library targets to users. include("@CLANG_CONFIG_EXPORTS_FILE@") diff --git a/gnu/llvm/clang/docs/AutomaticReferenceCounting.rst b/gnu/llvm/clang/docs/AutomaticReferenceCounting.rst index 9d61f58ed4d..c75ef025415 100644 --- a/gnu/llvm/clang/docs/AutomaticReferenceCounting.rst +++ b/gnu/llvm/clang/docs/AutomaticReferenceCounting.rst @@ -1100,32 +1100,282 @@ A pass-by-writeback is evaluated as follows: Ownership-qualified fields of structs and unions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A program is ill-formed if it declares a member of a C struct or union to have -a nontrivially ownership-qualified type. +A member of a struct or union may be declared to have ownership-qualified +type. If the type is qualified with ``__unsafe_unretained``, the semantics +of the containing aggregate are unchanged from the semantics of an unqualified type in a non-ARC mode. If the type is qualified with ``__autoreleasing``, the program is ill-formed. Otherwise, if the type is nontrivially ownership-qualified, additional rules apply. + +Both Objective-C and Objective-C++ support nontrivially ownership-qualified +fields. Due to formal differences between the standards, the formal +treatment is different; however, the basic language model is intended to +be the same for identical code. .. admonition:: Rationale - The resulting type would be non-POD in the C++ sense, but C does not give us - very good language tools for managing the lifetime of aggregates, so it is - more convenient to simply forbid them. It is still possible to manage this - with a ``void*`` or an ``__unsafe_unretained`` object. + Permitting ``__strong`` and ``__weak`` references in aggregate types + allows programmers to take advantage of the normal language tools of + C and C++ while still automatically managing memory. While it is + usually simpler and more idiomatic to use Objective-C objects for + secondary data structures, doing so can introduce extra allocation + and message-send overhead, which can cause to unacceptable + performance. Using structs can resolve some of this tension. + + ``__autoreleasing`` is forbidden because it is treacherous to rely + on autoreleases as an ownership tool outside of a function-local + contexts. + + Earlier releases of Clang permitted ``__strong`` and ``__weak`` only + references in Objective-C++ classes, not in Objective-C. This + restriction was an undesirable short-term constraint arising from the + complexity of adding support for non-trivial struct types to C. + +In Objective-C++, nontrivially ownership-qualified types are treated +for nearly all purposes as if they were class types with non-trivial +default constructors, copy constructors, move constructors, copy assignment +operators, move assignment operators, and destructors. This includes the +determination of the triviality of special members of classes with a +non-static data member of such a type. + +In Objective-C, the definition cannot be so succinct: because the C +standard lacks rules for non-trivial types, those rules must first be +developed. They are given in the next section. The intent is that these +rules are largely consistent with the rules of C++ for code expressible +in both languages. + +Formal rules for non-trivial types in C +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following are base rules which can be added to C to support +implementation-defined non-trivial types. + +A type in C is said to be *non-trivial to copy*, *non-trivial to destroy*, +or *non-trivial to default-initialize* if: + +- it is a struct or union containing a member whose type is non-trivial + to (respectively) copy, destroy, or default-initialize; + +- it is a qualified type whose unqualified type is non-trivial to + (respectively) copy, destroy, or default-initialize (for at least + the standard C qualifiers); or + +- it is an array type whose element type is non-trivial to (respectively) + copy, destroy, or default-initialize. + +A type in C is said to be *illegal to copy*, *illegal to destroy*, or +*illegal to default-initialize* if: + +- it is a union which contains a member whose type is either illegal + or non-trivial to (respectively) copy, destroy, or initialize; + +- it is a qualified type whose unqualified type is illegal to + (respectively) copy, destroy, or default-initialize (for at least + the standard C qualifiers); or + +- it is an array type whose element type is illegal to (respectively) + copy, destroy, or default-initialize. + +No type describable under the rules of the C standard shall be either +non-trivial or illegal to copy, destroy, or default-initialize. +An implementation may provide additional types which have one or more +of these properties. + +An expression calls for a type to be copied if it: + +- passes an argument of that type to a function call, +- defines a function which declares a parameter of that type, +- calls or defines a function which returns a value of that type, +- assigns to an l-value of that type, or +- converts an l-value of that type to an r-value. + +A program calls for a type to be destroyed if it: + +- passes an argument of that type to a function call, +- defines a function which declares a parameter of that type, +- calls or defines a function which returns a value of that type, +- creates an object of automatic storage duration of that type, +- assigns to an l-value of that type, or +- converts an l-value of that type to an r-value. + +A program calls for a type to be default-initialized if it: + +- declares a variable of that type without an initializer. + +An expression is ill-formed if calls for a type to be copied, +destroyed, or default-initialized and that type is illegal to +(respectively) copy, destroy, or default-initialize. + +A program is ill-formed if it contains a function type specifier +with a parameter or return type that is illegal to copy or +destroy. If a function type specifier would be ill-formed for this +reason except that the parameter or return type was incomplete at +that point in the translation unit, the program is ill-formed but +no diagnostic is required. + +A ``goto`` or ``switch`` is ill-formed if it jumps into the scope of +an object of automatic storage duration whose type is non-trivial to +destroy. + +C specifies that it is generally undefined behavior to access an l-value +if there is no object of that type at that location. Implementations +are often lenient about this, but non-trivial types generally require +it to be enforced more strictly. The following rules apply: + +The *static subobjects* of a type ``T`` at a location ``L`` are: + + - an object of type ``T`` spanning from ``L`` to ``L + sizeof(T)``; + + - if ``T`` is a struct type, then for each field ``f`` of that struct, + the static subobjects of ``T`` at location ``L + offsetof(T, .f)``; and + + - if ``T`` is the array type ``E[N]``, then for each ``i`` satisfying + ``0 <= i < N``, the static subobjects of ``E`` at location + ``L + i * sizeof(E)``. + +If an l-value is converted to an r-value, then all static subobjects +whose types are non-trivial to copy are accessed. If an l-value is +assigned to, or if an object of automatic storage duration goes out of +scope, then all static subobjects of types that are non-trivial to destroy +are accessed. + +A dynamic object is created at a location if an initialization initializes +an object of that type there. A dynamic object ceases to exist at a +location if the memory is repurposed. Memory is repurposed if it is +freed or if a different dynamic object is created there, for example by +assigning into a different union member. An implementation may provide +additional rules for what constitutes creating or destroying a dynamic +object. + +If an object is accessed under these rules at a location where no such +dynamic object exists, the program has undefined behavior. +If memory for a location is repurposed while a dynamic object that is +non-trivial to destroy exists at that location, the program has +undefined behavior. + +.. admonition:: Rationale -This restriction does not apply in Objective-C++. However, nontrivally -ownership-qualified types are considered non-POD: in C++11 terms, they are not -trivially default constructible, copy constructible, move constructible, copy -assignable, move assignable, or destructible. It is a violation of C++'s One -Definition Rule to use a class outside of ARC that, under ARC, would have a -nontrivially ownership-qualified member. + While these rules are far less fine-grained than C++, they are + nonetheless sufficient to express a wide spectrum of types. + Types that express some sort of ownership will generally be non-trivial + to both copy and destroy and either non-trivial or illegal to + default-initialize. Types that don't express ownership may still + be non-trivial to copy because of some sort of address sensitivity; + for example, a relative reference. Distinguishing default + initialization allows types to impose policies about how they are + created. + + These rules assume that assignment into an l-value is always a + modification of an existing object rather than an initialization. + Assignment is then a compound operation where the old value is + read and destroyed, if necessary, and the new value is put into + place. These are the natural semantics of value propagation, where + all basic operations on the type come down to copies and destroys, + and everything else is just an optimization on top of those. + + The most glaring weakness of programming with non-trivial types in C + is that there are no language mechanisms (akin to C++'s placement + ``new`` and explicit destructor calls) for explicitly creating and + destroying objects. Clang should consider adding builtins for this + purpose, as well as for common optimizations like destructive + relocation. + +Application of the formal C rules to nontrivial ownership qualifiers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Nontrivially ownership-qualified types are considered non-trivial +to copy, destroy, and default-initialize. + +A dynamic object of nontrivially ownership-qualified type contingently +exists at a location if the memory is filled with a zero pattern, e.g. +by ``calloc`` or ``bzero``. Such an object can be safely accessed in +all of the cases above, but its memory can also be safely repurposed. +Assigning a null pointer into an l-value of ``__weak`` or +``__strong``-qualified type accesses the dynamic object there (and thus +may have undefined behavior if no such object exists), but afterwards +the object's memory is guaranteed to be filled with a zero pattern +and thus may be either further accessed or repurposed as needed. +The upshot is that programs may safely initialize dynamically-allocated +memory for nontrivially ownership-qualified types by ensuring it is zero-initialized, and they may safely deinitialize memory before +freeing it by storing ``nil`` into any ``__strong`` or ``__weak`` +references previously created in that memory. + +C/C++ compatibility for structs and unions with non-trivial members +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Structs and unions with non-trivial members are compatible in +different language modes (e.g. between Objective-C and Objective-C++, +or between ARC and non-ARC modes) under the following conditions: + +- The types must be compatible ignoring ownership qualifiers according + to the baseline, non-ARC rules (e.g. C struct compatibility or C++'s + ODR). This condition implies a pairwise correspondance between + fields. + + Note that an Objective-C++ class with base classes, a user-provided + copy or move constructor, or a user-provided destructor is never + compatible with an Objective-C type. + +- If two fields correspond as above, and at least one of the fields is + ownership-qualified, then: + + - the fields must be identically qualified, or else + + - one type must be unqualified (and thus declared in a non-ARC mode), + and the other type must be qualified with ``__unsafe_unretained`` + or ``__strong``. + + Note that ``__weak`` fields must always be declared ``__weak`` because + of the need to pin those fields in memory and keep them properly + registered with the Objective-C runtime. Non-ARC modes may still + declare fields ``__weak`` by enabling ``-fobjc-weak``. + +These compatibility rules permit a function that takes a parameter +of non-trivial struct type to be written in ARC and called from +non-ARC or vice-versa. The convention for this always transfers +ownership of objects stored in ``__strong`` fields from the caller +to the callee, just as for an ``ns_consumed`` argument. Therefore, +non-ARC callers must ensure that such fields are initialized to a +1 +reference, and non-ARC callees must balance that +1 by releasing the +reference or transferring it as appropriate. + +Likewise, a function returning a non-trivial struct may be written in +ARC and called from non-ARC or vice-versa. The convention for this +always transfers ownership of objects stored in ``__strong`` fields +from the callee to the caller, and so callees must initialize such +fields with +1 references, and callers must balance that +1 by releasing +or transferring them. + +Similar transfers of responsibility occur for ``__weak`` fields, but +since both sides must use native ``__weak`` support to ensure +calling convention compatibililty, this transfer is always handled +automatically by the compiler. .. admonition:: Rationale - Unlike in C, we can express all the necessary ARC semantics for - ownership-qualified subobjects as suboperations of the (default) special - member functions for the class. These functions then become non-trivial. - This has the non-obvious result that the class will have a non-trivial copy - constructor and non-trivial destructor; if this would not normally be true - outside of ARC, objects of the type will be passed and returned in an - ABI-incompatible manner. + In earlier releases, when non-trivial ownership was only permitted + on fields in Objective-C++, the ABI used for such classees was the + ordinary ABI for non-trivial C++ classes, which passes arguments and + returns indirectly and does not transfer responsibility for arguments. + When support for Objective-C structs was added, it was decided to + change to the current ABI for three reasons: + + - It permits ARC / non-ARC compatibility for structs containing only + ``__strong`` references, as long as the non-ARC side is careful about + transferring ownership. + + - It avoids unnecessary indirection for sufficiently small types that + the C ABI would prefer to pass in registers. + + - Given that struct arguments must be produced at +1 to satisfy C's + semantics of initializing the local parameter variable, transferring + ownership of that copy to the callee is generally better for ARC + optimization, since otherwise there will be releases in the caller + that are much harder to pair with transfers in the callee. + + Breaking compatibility with existing Objective-C++ structures was + considered an acceptable cost, as most Objective-C++ code does not have + binary-compatibility requirements. Any existing code which cannot accept + this compatibility break, which is necessarily Objective-C++, should + force the use of the standard C++ ABI by declaring an empty (but + non-defaulted) destructor. .. _arc.ownership.inference: diff --git a/gnu/llvm/clang/docs/Block-ABI-Apple.rst b/gnu/llvm/clang/docs/Block-ABI-Apple.rst index 0cc14a35b03..d038cdfe9bd 100644 --- a/gnu/llvm/clang/docs/Block-ABI-Apple.rst +++ b/gnu/llvm/clang/docs/Block-ABI-Apple.rst @@ -63,7 +63,7 @@ The following flags bits are in use thusly for a possible ABI.2010.3.16: enum { // Set to true on blocks that have captures (and thus are not true // global blocks) but are known not to escape for various other - // reasons. For backward compatiblity with old runtimes, whenever + // reasons. For backward compatibility with old runtimes, whenever // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a // non-escaping block returns the original block and releasing such a // block is a no-op, which is exactly how global blocks are handled. diff --git a/gnu/llvm/clang/docs/CMakeLists.txt b/gnu/llvm/clang/docs/CMakeLists.txt index d2956c18f80..2d3ac5dbdd1 100644 --- a/gnu/llvm/clang/docs/CMakeLists.txt +++ b/gnu/llvm/clang/docs/CMakeLists.txt @@ -90,15 +90,43 @@ if (LLVM_ENABLE_DOXYGEN) endif() endif() +function (gen_rst_file_from_td output_file td_option source docs_target) + if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${source}") + message(FATAL_ERROR "Cannot find source file: ${source} in ${CMAKE_CURRENT_SOURCE_DIR}") + endif() + get_filename_component(TABLEGEN_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${source}" DIRECTORY) + list(APPEND LLVM_TABLEGEN_FLAGS "-I${TABLEGEN_INCLUDE_DIR}") + clang_tablegen(${output_file} ${td_option} SOURCE ${source} TARGET "gen-${output_file}") + add_dependencies(${docs_target} "gen-${output_file}") +endfunction() + if (LLVM_ENABLE_SPHINX) include(AddSphinxTarget) if (SPHINX_FOUND) if (${SPHINX_OUTPUT_HTML}) - add_sphinx_target(html clang) + add_sphinx_target(html clang SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + # Copy rst files to build directory before generating the html + # documentation. Some of the rst files are generated, so they + # only exist in the build directory. Sphinx needs all files in + # the same directory in order to generate the html, so we need to + # copy all the non-gnerated rst files from the source to the build + # directory before we run sphinx. + add_custom_target(copy-clang-rst-docs + COMMAND "${CMAKE_COMMAND}" -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}") + add_dependencies(docs-clang-html copy-clang-rst-docs) + add_custom_command(TARGET docs-clang-html POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibASTMatchersReference.html" "${CMAKE_CURRENT_BINARY_DIR}/html/LibASTMatchersReference.html") + + # Generated files + gen_rst_file_from_td(AttributeReference.rst -gen-attr-docs ../include/clang/Basic/Attr.td docs-clang-html) + gen_rst_file_from_td(DiagnosticsReference.rst -gen-diag-docs ../include/clang/Basic/Diagnostic.td docs-clang-html) + gen_rst_file_from_td(ClangCommandLineReference.rst -gen-opt-docs ../include/clang/Driver/ClangOptionDocs.td docs-clang-html) endif() if (${SPHINX_OUTPUT_MAN}) add_sphinx_target(man clang) diff --git a/gnu/llvm/clang/docs/ClangFormat.rst b/gnu/llvm/clang/docs/ClangFormat.rst index 1138b233267..b09f48b0027 100644 --- a/gnu/llvm/clang/docs/ClangFormat.rst +++ b/gnu/llvm/clang/docs/ClangFormat.rst @@ -173,16 +173,17 @@ shortcut in the BBEdit preferences, under Menus & Shortcuts. CLion Integration -================== +================= :program:`clang-format` is integrated into `CLion `_ as an alternative code formatter. It is disabled by default and -can be turned on in Settings/Preferences | Editor | Code Style. +.com/clion/>`_ as an alternative code formatter. CLion turns it on +automatically when there is a ``.clang-format`` file under the project root. +Code style rules are applied as you type, including indentation, +auto-completion, code generation, and refactorings. -If :program:`clang-format` support is enabled, CLion detects config files when -opening a project and suggests overriding the current IDE settings. Code style -rules from the ``.clang-format`` files are then applied automatically to all -editor actions, including auto-completion, code generation, and refactorings. +:program:`clang-format` can also be enabled without a ``.clang-format`` file. +In this case, CLion prompts you to create one based on the current IDE settings +or the default LLVM style. Visual Studio Integration @@ -192,6 +193,12 @@ Download the latest Visual Studio extension from the `alpha build site `_. The default key-binding is Ctrl-R,Ctrl-F. +Visual Studio Code Integration +============================== + +Get the latest Visual Studio Code extension from the `Visual Studio Marketplace `_. The default key-binding is Alt-Shift-F. + + Script for patch reformatting ============================= @@ -234,3 +241,8 @@ In an SVN client, you can do: The option `-U0` will create a diff without context lines (the script would format those as well). + +Current State of Clang Format for LLVM +====================================== + +The following table :doc:`ClangFormattedStatus` shows the current status of clang-formatting for the entire LLVM source tree. diff --git a/gnu/llvm/clang/docs/ClangFormatStyleOptions.rst b/gnu/llvm/clang/docs/ClangFormatStyleOptions.rst index 18cdc54a370..e84676760c3 100644 --- a/gnu/llvm/clang/docs/ClangFormatStyleOptions.rst +++ b/gnu/llvm/clang/docs/ClangFormatStyleOptions.rst @@ -151,6 +151,9 @@ the configuration (without a prefix: ``Auto``). * ``Microsoft`` A style complying with `Microsoft's style guide `_ + * ``GNU`` + A style complying with the `GNU coding standards + `_ .. START_FORMAT_STYLE_OPTIONS @@ -204,6 +207,18 @@ the configuration (without a prefix: ``Auto``). int b = 23; int ccc = 23; +**AlignConsecutiveBitFields** (``bool``) + If ``true``, aligns consecutive bitfield members. + + This will align the bitfield separators of consecutive lines. This + will result in formattings like + + .. code-block:: c++ + + int aaaa : 1; + int b : 12; + int ccc : 8; + **AlignConsecutiveDeclarations** (``bool``) If ``true``, aligns consecutive declarations. @@ -270,17 +285,49 @@ the configuration (without a prefix: ``Auto``). -**AlignOperands** (``bool``) +**AlignOperands** (``OperandAlignmentStyle``) If ``true``, horizontally align operands of binary and ternary expressions. - Specifically, this aligns operands of a single expression that needs to be - split over multiple lines, e.g.: + Possible values: + + * ``OAS_DontAlign`` (in configuration: ``DontAlign``) + Do not align operands of binary and ternary expressions. + The wrapped lines are indented ``ContinuationIndentWidth`` spaces from + the start of the line. + + * ``OAS_Align`` (in configuration: ``Align``) + Horizontally align operands of binary and ternary expressions. + + Specifically, this aligns operands of a single expression that needs + to be split over multiple lines, e.g.: + + .. code-block:: c++ + + int aaa = bbbbbbbbbbbbbbb + + ccccccccccccccc; + + When ``BreakBeforeBinaryOperators`` is set, the wrapped operator is + aligned with the operand on the first line. + + .. code-block:: c++ + + int aaa = bbbbbbbbbbbbbbb + + ccccccccccccccc; + + * ``OAS_AlignAfterOperator`` (in configuration: ``AlignAfterOperator``) + Horizontally align operands of binary and ternary expressions. + + This is similar to ``AO_Align``, except when + ``BreakBeforeBinaryOperators`` is set, the operator is un-indented so + that the wrapped operand is aligned with the operand on the first line. + + .. code-block:: c++ + + int aaa = bbbbbbbbbbbbbbb + + ccccccccccccccc; - .. code-block:: c++ - int aaa = bbbbbbbbbbbbbbb + - ccccccccccccccc; **AlignTrailingComments** (``bool``) If ``true``, aligns trailing comments. @@ -395,6 +442,21 @@ the configuration (without a prefix: ``Auto``). return; } +**AllowShortEnumsOnASingleLine** (``bool``) + Allow short enums on a single line. + + .. code-block:: c++ + + true: + enum { A, B } myEnum; + + false: + enum + { + A, + B + } myEnum; + **AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``) Dependent on the value, ``int f() { return 0; }`` can be put on a single line. @@ -948,6 +1010,39 @@ the configuration (without a prefix: ``Auto``). } else { } + * ``bool BeforeLambdaBody`` Wrap lambda block. + + .. code-block:: c++ + + true: + connect( + []() + { + foo(); + bar(); + }); + + false: + connect([]() { + foo(); + bar(); + }); + + * ``bool BeforeWhile`` Wrap before ``while``. + + .. code-block:: c++ + + true: + do { + foo(); + } + while (1); + + false: + do { + foo(); + } while (1); + * ``bool IndentBraces`` Indent the wrapped braces themselves. * ``bool SplitEmptyFunction`` If ``false``, empty function body can be put on a single line. @@ -1605,12 +1700,36 @@ the configuration (without a prefix: ``Auto``). ``ClassImpl.hpp`` would not have the main include file put on top before any other include. +**IndentCaseBlocks** (``bool``) + Indent case label blocks one level from the case label. + + When ``false``, the block following the case label uses the same + indentation level as for the case label, treating the case label the same + as an if-statement. + When ``true``, the block gets indented as a scope block. + + .. code-block:: c++ + + false: true: + switch (fool) { vs. switch (fool) { + case 1: { case 1: + bar(); { + } break; bar(); + default: { } + plop(); break; + } default: + } { + plop(); + } + } + **IndentCaseLabels** (``bool``) Indent case labels one level from the switch statement. When ``false``, use the same indentation level as for the switch statement. Switch statement body is always indented one level more than - case labels. + case labels (except the first block following the case label, which + itself indents the code - unless IndentCaseBlocks is enabled). .. code-block:: c++ @@ -1623,6 +1742,52 @@ the configuration (without a prefix: ``Auto``). plop(); plop(); } } +**IndentExternBlock** (``IndentExternBlockStyle``) + IndentExternBlockStyle is the type of indenting of extern blocks. + + Possible values: + + * ``IEBS_AfterExternBlock`` (in configuration: ``AfterExternBlock``) + Backwards compatible with AfterExternBlock's indenting. + + .. code-block:: c++ + + IndentExternBlock: AfterExternBlock + BraceWrapping.AfterExternBlock: true + extern "C" + { + void foo(); + } + + + .. code-block:: c++ + + IndentExternBlock: AfterExternBlock + BraceWrapping.AfterExternBlock: false + extern "C" { + void foo(); + } + + * ``IEBS_NoIndent`` (in configuration: ``NoIndent``) + Does not indent extern blocks. + + .. code-block:: c++ + + extern "C" { + void foo(); + } + + * ``IEBS_Indent`` (in configuration: ``Indent``) + Indents extern blocks. + + .. code-block:: c++ + + extern "C" { + void foo(); + } + + + **IndentGotoLabels** (``bool``) Indent goto labels. @@ -1708,6 +1873,38 @@ the configuration (without a prefix: ``Auto``). LoooooooooooooooooooooooooooooooooooooooongReturnType LoooooooooooooooooooooooooooooooongFunctionDeclaration(); +**InsertTrailingCommas** (``TrailingCommaStyle``) + If set to ``TCS_Wrapped`` will insert trailing commas in container + literals (arrays and objects) that wrap across multiple lines. + It is currently only available for JavaScript + and disabled by default ``TCS_None``. + ``InsertTrailingCommas`` cannot be used together with ``BinPackArguments`` + as inserting the comma disables bin-packing. + + .. code-block:: c++ + + TSC_Wrapped: + const someArray = [ + aaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaaa, + aaaaaaaaaaaaaaaaaaaaaaaaaa, + // ^ inserted + ] + + Possible values: + + * ``TCS_None`` (in configuration: ``None``) + Do not insert trailing commas. + + * ``TCS_Wrapped`` (in configuration: ``Wrapped``) + Insert trailing commas in container literals that were wrapped over + multiple lines. Note that this is conceptually incompatible with + bin-packing, because the trailing comma is used as an indicator + that a container should be formatted one-per-line (i.e. not bin-packed). + So inserting a trailing comma counteracts bin-packing. + + + **JavaImportGroups** (``std::vector``) A vector of prefixes ordered by the desired groups for Java imports. @@ -1993,6 +2190,30 @@ the configuration (without a prefix: ``Auto``). [self onOperationDone]; }]; +**ObjCBreakBeforeNestedBlockParam** (``bool``) + Break parameters list into lines when there is nested block + parameters in a fuction call. + + .. code-block:: c++ + + false: + - (void)_aMethod + { + [self.test1 t:self w:self callback:^(typeof(self) self, NSNumber + *u, NSNumber *v) { + u = c; + }] + } + true: + - (void)_aMethod + { + [self.test1 t:self + w:self + callback:^(typeof(self) self, NSNumber *u, NSNumber *v) { + u = c; + }] + } + **ObjCSpaceAfterProperty** (``bool``) Add a space after ``@property`` in Objective-C, i.e. use ``@property (readonly)`` instead of ``@property(readonly)``. @@ -2223,6 +2444,19 @@ the configuration (without a prefix: ``Auto``). } } + * ``SBPO_ControlStatementsExceptForEachMacros`` (in configuration: ``ControlStatementsExceptForEachMacros``) + Same as ``SBPO_ControlStatements`` except this option doesn't apply to + ForEach macros. This is useful in projects where ForEach macros are + treated as function calls instead of control statements. + + .. code-block:: c++ + + void f() { + Q_FOREACH(...) { + f(); + } + } + * ``SBPO_NonEmptyParentheses`` (in configuration: ``NonEmptyParentheses``) Put a space before opening parentheses only if the parentheses are not empty i.e. '()' @@ -2329,7 +2563,14 @@ the configuration (without a prefix: ``Auto``). x = ( int32 )y vs. x = (int32)y **SpacesInConditionalStatement** (``bool``) - If ``true``, spaces will be inserted around if/for/while (and similar) conditions. + If ``true``, spaces will be inserted around if/for/switch/while + conditions. + + .. code-block:: c++ + + true: false: + if ( a ) { ... } vs. if (a) { ... } + while ( i < 5 ) { ... } while (i < 5) { ... } **SpacesInContainerLiterals** (``bool``) If ``true``, spaces are inserted inside container literals (e.g. @@ -2442,12 +2683,34 @@ the configuration (without a prefix: ``Auto``). Use tabs only for indentation. * ``UT_ForContinuationAndIndentation`` (in configuration: ``ForContinuationAndIndentation``) - Use tabs only for line continuation and indentation. + Fill all leading whitespace with tabs, and use spaces for alignment that + appears within a line (e.g. consecutive assignments and declarations). + + * ``UT_AlignWithSpaces`` (in configuration: ``AlignWithSpaces``) + Use tabs for line continuation and indentation, and spaces for + alignment. * ``UT_Always`` (in configuration: ``Always``) Use tabs whenever we need to fill whitespace that spans at least from one tab stop to the next one. +**WhitespaceSensitiveMacros** (``std::vector``) + A vector of macros which are whitespace-sensitive and should not be touched. + + These are expected to be macros of the form: + + .. code-block:: c++ + + STRINGIZE(...) + + In the .clang-format configuration file, this can be configured like: + + .. code-block:: yaml + + WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE'] + + For example: BOOST_PP_STRINGIZE. + .. END_FORMAT_STYLE_OPTIONS diff --git a/gnu/llvm/clang/docs/ClangFormattedStatus.rst b/gnu/llvm/clang/docs/ClangFormattedStatus.rst new file mode 100644 index 00000000000..3e348eadd4f --- /dev/null +++ b/gnu/llvm/clang/docs/ClangFormattedStatus.rst @@ -0,0 +1,6866 @@ +.. raw:: html + + + +.. role:: none +.. role:: part +.. role:: good +.. role:: total + +====================== +Clang Formatted Status +====================== + +:doc:`ClangFormattedStatus` describes the state of LLVM source +tree in terms of conformance to :doc:`ClangFormat` as of: June 27, 2020 11:36:24 (`eb50838ba08 `_). + + +.. list-table:: LLVM Clang-Format Status + :widths: 50 25 25 25 25 + :header-rows: 1 + + * - Directory + - Total Files + - Formatted Files + - Unformatted Files + - % Complete + * - clang/bindings/python/tests/cindex/INPUTS + - `5` + - `3` + - `2` + - :part:`60%` + * - clang/docs/analyzer/checkers + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/examples/AnnotateFunctions + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/examples/Attribute + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/examples/clang-interpreter + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/examples/PrintFunctionNames + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/include/clang/Analysis + - `14` + - `3` + - `11` + - :part:`21%` + * - clang/include/clang/Analysis/Analyses + - `14` + - `2` + - `12` + - :part:`14%` + * - clang/include/clang/Analysis/DomainSpecific + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/include/clang/Analysis/FlowSensitive + - `2` + - `1` + - `1` + - :part:`50%` + * - clang/include/clang/Analysis/Support + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/include/clang/ARCMigrate + - `3` + - `0` + - `3` + - :none:`0%` + * - clang/include/clang/AST + - `113` + - `20` + - `93` + - :part:`17%` + * - clang/include/clang/ASTMatchers + - `5` + - `1` + - `4` + - :part:`20%` + * - clang/include/clang/ASTMatchers/Dynamic + - `4` + - `1` + - `3` + - :part:`25%` + * - clang/include/clang/Basic + - `76` + - `26` + - `50` + - :part:`34%` + * - clang/include/clang/CodeGen + - `9` + - `0` + - `9` + - :none:`0%` + * - clang/include/clang/CrossTU + - `2` + - `1` + - `1` + - :part:`50%` + * - clang/include/clang/DirectoryWatcher + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/include/clang/Driver + - `17` + - `4` + - `13` + - :part:`23%` + * - clang/include/clang/Edit + - `5` + - `1` + - `4` + - :part:`20%` + * - clang/include/clang/Format + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/include/clang/Frontend + - `28` + - `7` + - `21` + - :part:`25%` + * - clang/include/clang/FrontendTool + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/include/clang/Index + - `7` + - `2` + - `5` + - :part:`28%` + * - clang/include/clang/Lex + - `29` + - `4` + - `25` + - :part:`13%` + * - clang/include/clang/Parse + - `5` + - `2` + - `3` + - :part:`40%` + * - clang/include/clang/Rewrite/Core + - `6` + - `0` + - `6` + - :none:`0%` + * - clang/include/clang/Rewrite/Frontend + - `4` + - `0` + - `4` + - :none:`0%` + * - clang/include/clang/Sema + - `32` + - `3` + - `29` + - :part:`9%` + * - clang/include/clang/Serialization + - `14` + - `2` + - `12` + - :part:`14%` + * - clang/include/clang/StaticAnalyzer/Checkers + - `4` + - `1` + - `3` + - :part:`25%` + * - clang/include/clang/StaticAnalyzer/Core + - `5` + - `1` + - `4` + - :part:`20%` + * - clang/include/clang/StaticAnalyzer/Core/BugReporter + - `4` + - `1` + - `3` + - :part:`25%` + * - clang/include/clang/StaticAnalyzer/Core/PathSensitive + - `36` + - `9` + - `27` + - :part:`25%` + * - clang/include/clang/StaticAnalyzer/Frontend + - `5` + - `3` + - `2` + - :part:`60%` + * - clang/include/clang/Testing + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/include/clang/Tooling + - `16` + - `9` + - `7` + - :part:`56%` + * - clang/include/clang/Tooling/ASTDiff + - `2` + - `2` + - `0` + - :good:`100%` + * - clang/include/clang/Tooling/Core + - `3` + - `1` + - `2` + - :part:`33%` + * - clang/include/clang/Tooling/DependencyScanning + - `5` + - `4` + - `1` + - :part:`80%` + * - clang/include/clang/Tooling/Inclusions + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/include/clang/Tooling/Refactoring + - `14` + - `12` + - `2` + - :part:`85%` + * - clang/include/clang/Tooling/Refactoring/Extract + - `2` + - `1` + - `1` + - :part:`50%` + * - clang/include/clang/Tooling/Refactoring/Rename + - `6` + - `5` + - `1` + - :part:`83%` + * - clang/include/clang/Tooling/Syntax + - `5` + - `5` + - `0` + - :good:`100%` + * - clang/include/clang/Tooling/Transformer + - `8` + - `7` + - `1` + - :part:`87%` + * - clang/include/clang-c + - `9` + - `3` + - `6` + - :part:`33%` + * - clang/INPUTS + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/lib/Analysis + - `25` + - `2` + - `23` + - :part:`8%` + * - clang/lib/Analysis/plugins/CheckerDependencyHandling + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/lib/Analysis/plugins/CheckerOptionHandling + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/Analysis/plugins/SampleAnalyzer + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/lib/ARCMigrate + - `22` + - `0` + - `22` + - :none:`0%` + * - clang/lib/AST + - `80` + - `2` + - `78` + - :part:`2%` + * - clang/lib/AST/Interp + - `44` + - `19` + - `25` + - :part:`43%` + * - clang/lib/ASTMatchers + - `3` + - `0` + - `3` + - :none:`0%` + * - clang/lib/ASTMatchers/Dynamic + - `6` + - `1` + - `5` + - :part:`16%` + * - clang/lib/Basic + - `34` + - `8` + - `26` + - :part:`23%` + * - clang/lib/Basic/Targets + - `48` + - `23` + - `25` + - :part:`47%` + * - clang/lib/CodeGen + - `87` + - `8` + - `79` + - :part:`9%` + * - clang/lib/CrossTU + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/DirectoryWatcher + - `2` + - `2` + - `0` + - :good:`100%` + * - clang/lib/DirectoryWatcher/default + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/DirectoryWatcher/linux + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/DirectoryWatcher/mac + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/DirectoryWatcher/windows + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/Driver + - `16` + - `2` + - `14` + - :part:`12%` + * - clang/lib/Driver/ToolChains + - `83` + - `27` + - `56` + - :part:`32%` + * - clang/lib/Driver/ToolChains/Arch + - `18` + - `4` + - `14` + - :part:`22%` + * - clang/lib/Edit + - `3` + - `0` + - `3` + - :none:`0%` + * - clang/lib/Format + - `29` + - `29` + - `0` + - :good:`100%` + * - clang/lib/Format/old + - `2` + - `1` + - `1` + - :part:`50%` + * - clang/lib/Frontend + - `33` + - `4` + - `29` + - :part:`12%` + * - clang/lib/Frontend/Rewrite + - `8` + - `0` + - `8` + - :none:`0%` + * - clang/lib/FrontendTool + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/Headers + - `129` + - `12` + - `117` + - :part:`9%` + * - clang/lib/Headers/openmp_wrappers + - `3` + - `3` + - `0` + - :good:`100%` + * - clang/lib/Headers/ppc_wrappers + - `7` + - `2` + - `5` + - :part:`28%` + * - clang/lib/Index + - `12` + - `2` + - `10` + - :part:`16%` + * - clang/lib/Lex + - `23` + - `1` + - `22` + - :part:`4%` + * - clang/lib/Parse + - `15` + - `0` + - `15` + - :none:`0%` + * - clang/lib/Rewrite + - `5` + - `0` + - `5` + - :none:`0%` + * - clang/lib/Sema + - `55` + - `4` + - `51` + - :part:`7%` + * - clang/lib/Serialization + - `17` + - `1` + - `16` + - :part:`5%` + * - clang/lib/StaticAnalyzer/Checkers + - `115` + - `13` + - `102` + - :part:`11%` + * - clang/lib/StaticAnalyzer/Checkers/cert + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/lib/StaticAnalyzer/Checkers/MPI-Checker + - `6` + - `0` + - `6` + - :none:`0%` + * - clang/lib/StaticAnalyzer/Checkers/RetainCountChecker + - `4` + - `0` + - `4` + - :none:`0%` + * - clang/lib/StaticAnalyzer/Checkers/UninitializedObject + - `3` + - `1` + - `2` + - :part:`33%` + * - clang/lib/StaticAnalyzer/Checkers/WebKit + - `8` + - `6` + - `2` + - :part:`75%` + * - clang/lib/StaticAnalyzer/Core + - `46` + - `8` + - `38` + - :part:`17%` + * - clang/lib/StaticAnalyzer/Frontend + - `8` + - `3` + - `5` + - :part:`37%` + * - clang/lib/Testing + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/lib/Tooling + - `15` + - `6` + - `9` + - :part:`40%` + * - clang/lib/Tooling/ASTDiff + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/lib/Tooling/Core + - `3` + - `1` + - `2` + - :part:`33%` + * - clang/lib/Tooling/DependencyScanning + - `5` + - `2` + - `3` + - :part:`40%` + * - clang/lib/Tooling/Inclusions + - `2` + - `2` + - `0` + - :good:`100%` + * - clang/lib/Tooling/Refactoring + - `4` + - `2` + - `2` + - :part:`50%` + * - clang/lib/Tooling/Refactoring/Extract + - `2` + - `1` + - `1` + - :part:`50%` + * - clang/lib/Tooling/Refactoring/Rename + - `5` + - `2` + - `3` + - :part:`40%` + * - clang/lib/Tooling/Syntax + - `7` + - `6` + - `1` + - :part:`85%` + * - clang/lib/Tooling/Transformer + - `7` + - `4` + - `3` + - :part:`57%` + * - clang/tools/arcmt-test + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/c-index-test + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-check + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-diff + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-extdef-mapping + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-format + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/tools/clang-format/fuzzer + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-fuzzer + - `6` + - `4` + - `2` + - :part:`66%` + * - clang/tools/clang-fuzzer/fuzzer-initialize + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/tools/clang-fuzzer/handle-cxx + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/tools/clang-fuzzer/handle-llvm + - `3` + - `1` + - `2` + - :part:`33%` + * - clang/tools/clang-fuzzer/proto-to-cxx + - `5` + - `0` + - `5` + - :none:`0%` + * - clang/tools/clang-fuzzer/proto-to-llvm + - `3` + - `0` + - `3` + - :none:`0%` + * - clang/tools/clang-import-test + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/tools/clang-offload-bundler + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-offload-wrapper + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/tools/clang-refactor + - `4` + - `4` + - `0` + - :good:`100%` + * - clang/tools/clang-rename + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/tools/clang-scan-deps + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/tools/clang-shlib + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/tools/diagtool + - `9` + - `0` + - `9` + - :none:`0%` + * - clang/tools/driver + - `4` + - `1` + - `3` + - :part:`25%` + * - clang/tools/libclang + - `34` + - `6` + - `28` + - :part:`17%` + * - clang/tools/scan-build-py/tests/functional/src/include + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/unittests/Analysis + - `5` + - `2` + - `3` + - :part:`40%` + * - clang/unittests/AST + - `27` + - `6` + - `21` + - :part:`22%` + * - clang/unittests/ASTMatchers + - `6` + - `0` + - `6` + - :none:`0%` + * - clang/unittests/ASTMatchers/Dynamic + - `3` + - `0` + - `3` + - :none:`0%` + * - clang/unittests/Basic + - `5` + - `1` + - `4` + - :part:`20%` + * - clang/unittests/CodeGen + - `5` + - `0` + - `5` + - :none:`0%` + * - clang/unittests/CrossTU + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/unittests/DirectoryWatcher + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/unittests/Driver + - `5` + - `1` + - `4` + - :part:`20%` + * - clang/unittests/Format + - `18` + - `17` + - `1` + - :part:`94%` + * - clang/unittests/Frontend + - `9` + - `5` + - `4` + - :part:`55%` + * - clang/unittests/Index + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/unittests/Lex + - `6` + - `1` + - `5` + - :part:`16%` + * - clang/unittests/libclang + - `2` + - `0` + - `2` + - :none:`0%` + * - clang/unittests/libclang/CrashTests + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/unittests/Rename + - `6` + - `0` + - `6` + - :none:`0%` + * - clang/unittests/Rewrite + - `2` + - `1` + - `1` + - :part:`50%` + * - clang/unittests/Sema + - `3` + - `2` + - `1` + - :part:`66%` + * - clang/unittests/Serialization + - `1` + - `1` + - `0` + - :good:`100%` + * - clang/unittests/StaticAnalyzer + - `11` + - `4` + - `7` + - :part:`36%` + * - clang/unittests/Tooling + - `29` + - `7` + - `22` + - :part:`24%` + * - clang/unittests/Tooling/RecursiveASTVisitorTests + - `23` + - `9` + - `14` + - :part:`39%` + * - clang/unittests/Tooling/Syntax + - `2` + - `2` + - `0` + - :good:`100%` + * - clang/utils/perf-training/cxx + - `1` + - `0` + - `1` + - :none:`0%` + * - clang/utils/TableGen + - `20` + - `2` + - `18` + - :part:`10%` + * - clang-tools-extra/clang-apply-replacements/include/clang-apply-replacements/Tooling + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-apply-replacements/lib/Tooling + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-apply-replacements/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-change-namespace + - `2` + - `0` + - `2` + - :none:`0%` + * - clang-tools-extra/clang-change-namespace/tool + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/clang-doc + - `17` + - `16` + - `1` + - :part:`94%` + * - clang-tools-extra/clang-doc/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-include-fixer + - `13` + - `7` + - `6` + - :part:`53%` + * - clang-tools-extra/clang-include-fixer/find-all-symbols + - `17` + - `13` + - `4` + - :part:`76%` + * - clang-tools-extra/clang-include-fixer/find-all-symbols/tool + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/clang-include-fixer/plugin + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-include-fixer/tool + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/clang-move + - `4` + - `1` + - `3` + - :part:`25%` + * - clang-tools-extra/clang-move/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-query + - `5` + - `3` + - `2` + - :part:`60%` + * - clang-tools-extra/clang-query/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-reorder-fields + - `2` + - `1` + - `1` + - :part:`50%` + * - clang-tools-extra/clang-reorder-fields/tool + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/clang-tidy + - `18` + - `10` + - `8` + - :part:`55%` + * - clang-tools-extra/clang-tidy/abseil + - `40` + - `28` + - `12` + - :part:`70%` + * - clang-tools-extra/clang-tidy/android + - `33` + - `23` + - `10` + - :part:`69%` + * - clang-tools-extra/clang-tidy/boost + - `3` + - `3` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-tidy/bugprone + - `105` + - `85` + - `20` + - :part:`80%` + * - clang-tools-extra/clang-tidy/cert + - `29` + - `27` + - `2` + - :part:`93%` + * - clang-tools-extra/clang-tidy/cppcoreguidelines + - `41` + - `38` + - `3` + - :part:`92%` + * - clang-tools-extra/clang-tidy/darwin + - `5` + - `2` + - `3` + - :part:`40%` + * - clang-tools-extra/clang-tidy/fuchsia + - `15` + - `9` + - `6` + - :part:`60%` + * - clang-tools-extra/clang-tidy/google + - `35` + - `23` + - `12` + - :part:`65%` + * - clang-tools-extra/clang-tidy/hicpp + - `9` + - `6` + - `3` + - :part:`66%` + * - clang-tools-extra/clang-tidy/linuxkernel + - `3` + - `2` + - `1` + - :part:`66%` + * - clang-tools-extra/clang-tidy/llvm + - `11` + - `10` + - `1` + - :part:`90%` + * - clang-tools-extra/clang-tidy/llvmlibc + - `7` + - `7` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-tidy/misc + - `29` + - `25` + - `4` + - :part:`86%` + * - clang-tools-extra/clang-tidy/modernize + - `67` + - `46` + - `21` + - :part:`68%` + * - clang-tools-extra/clang-tidy/mpi + - `5` + - `4` + - `1` + - :part:`80%` + * - clang-tools-extra/clang-tidy/objc + - `15` + - `10` + - `5` + - :part:`66%` + * - clang-tools-extra/clang-tidy/openmp + - `5` + - `5` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-tidy/performance + - `29` + - `24` + - `5` + - :part:`82%` + * - clang-tools-extra/clang-tidy/plugin + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clang-tidy/portability + - `5` + - `3` + - `2` + - :part:`60%` + * - clang-tools-extra/clang-tidy/readability + - `77` + - `63` + - `14` + - :part:`81%` + * - clang-tools-extra/clang-tidy/tool + - `3` + - `2` + - `1` + - :part:`66%` + * - clang-tools-extra/clang-tidy/utils + - `33` + - `26` + - `7` + - :part:`78%` + * - clang-tools-extra/clang-tidy/zircon + - `3` + - `3` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd + - `75` + - `58` + - `17` + - :part:`77%` + * - clang-tools-extra/clangd/benchmarks + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/fuzzer + - `2` + - `2` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/index + - `37` + - `34` + - `3` + - :part:`91%` + * - clang-tools-extra/clangd/index/dex + - `9` + - `8` + - `1` + - :part:`88%` + * - clang-tools-extra/clangd/index/dex/dexp + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/index/remote + - `2` + - `2` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/index/remote/marshalling + - `2` + - `2` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/index/remote/server + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/index/remote/unimplemented + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/indexer + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/refactor + - `4` + - `4` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/refactor/tweaks + - `13` + - `10` + - `3` + - :part:`76%` + * - clang-tools-extra/clangd/support + - `18` + - `18` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/unittests + - `64` + - `52` + - `12` + - :part:`81%` + * - clang-tools-extra/clangd/unittests/remote + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/unittests/support + - `8` + - `8` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/unittests/xpc + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/xpc + - `3` + - `3` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/xpc/framework + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/clangd/xpc/test-client + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/modularize + - `9` + - `1` + - `8` + - :part:`11%` + * - clang-tools-extra/pp-trace + - `3` + - `1` + - `2` + - :part:`33%` + * - clang-tools-extra/tool-template + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/unittests/clang-apply-replacements + - `1` + - `1` + - `0` + - :good:`100%` + * - clang-tools-extra/unittests/clang-change-namespace + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/unittests/clang-doc + - `9` + - `9` + - `0` + - :good:`100%` + * - clang-tools-extra/unittests/clang-include-fixer + - `2` + - `0` + - `2` + - :none:`0%` + * - clang-tools-extra/unittests/clang-include-fixer/find-all-symbols + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/unittests/clang-move + - `1` + - `0` + - `1` + - :none:`0%` + * - clang-tools-extra/unittests/clang-query + - `2` + - `0` + - `2` + - :none:`0%` + * - clang-tools-extra/unittests/clang-tidy + - `14` + - `6` + - `8` + - :part:`42%` + * - clang-tools-extra/unittests/include/common + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/include/fuzzer + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/include/sanitizer + - `14` + - `1` + - `13` + - :part:`7%` + * - compiler-rt/include/xray + - `3` + - `2` + - `1` + - :part:`66%` + * - compiler-rt/lib/asan + - `59` + - `3` + - `56` + - :part:`5%` + * - compiler-rt/lib/asan/tests + - `17` + - `1` + - `16` + - :part:`5%` + * - compiler-rt/lib/BlocksRuntime + - `2` + - `0` + - `2` + - :none:`0%` + * - compiler-rt/lib/builtins + - `11` + - `9` + - `2` + - :part:`81%` + * - compiler-rt/lib/builtins/arm + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/builtins/ppc + - `1` + - `1` + - `0` + - :good:`100%` + * - compiler-rt/lib/cfi + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/dfsan + - `5` + - `0` + - `5` + - :none:`0%` + * - compiler-rt/lib/fuzzer + - `43` + - `5` + - `38` + - :part:`11%` + * - compiler-rt/lib/fuzzer/afl + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/fuzzer/dataflow + - `3` + - `0` + - `3` + - :none:`0%` + * - compiler-rt/lib/fuzzer/tests + - `2` + - `1` + - `1` + - :part:`50%` + * - compiler-rt/lib/gwp_asan + - `14` + - `13` + - `1` + - :part:`92%` + * - compiler-rt/lib/gwp_asan/optional + - `7` + - `7` + - `0` + - :good:`100%` + * - compiler-rt/lib/gwp_asan/platform_specific + - `4` + - `4` + - `0` + - :good:`100%` + * - compiler-rt/lib/gwp_asan/tests + - `14` + - `14` + - `0` + - :good:`100%` + * - compiler-rt/lib/gwp_asan/tests/optional + - `1` + - `1` + - `0` + - :good:`100%` + * - compiler-rt/lib/hwasan + - `27` + - `7` + - `20` + - :part:`25%` + * - compiler-rt/lib/interception + - `8` + - `1` + - `7` + - :part:`12%` + * - compiler-rt/lib/interception/tests + - `3` + - `1` + - `2` + - :part:`33%` + * - compiler-rt/lib/lsan + - `20` + - `7` + - `13` + - :part:`35%` + * - compiler-rt/lib/msan + - `18` + - `4` + - `14` + - :part:`22%` + * - compiler-rt/lib/msan/tests + - `4` + - `0` + - `4` + - :none:`0%` + * - compiler-rt/lib/profile + - `6` + - `0` + - `6` + - :none:`0%` + * - compiler-rt/lib/safestack + - `3` + - `1` + - `2` + - :part:`33%` + * - compiler-rt/lib/sanitizer_common + - `159` + - `23` + - `136` + - :part:`14%` + * - compiler-rt/lib/sanitizer_common/symbolizer + - `2` + - `2` + - `0` + - :good:`100%` + * - compiler-rt/lib/sanitizer_common/tests + - `38` + - `1` + - `37` + - :part:`2%` + * - compiler-rt/lib/scudo + - `20` + - `0` + - `20` + - :none:`0%` + * - compiler-rt/lib/scudo/standalone + - `46` + - `42` + - `4` + - :part:`91%` + * - compiler-rt/lib/scudo/standalone/benchmarks + - `1` + - `1` + - `0` + - :good:`100%` + * - compiler-rt/lib/scudo/standalone/fuzz + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/scudo/standalone/include/scudo + - `1` + - `1` + - `0` + - :good:`100%` + * - compiler-rt/lib/scudo/standalone/tests + - `23` + - `23` + - `0` + - :good:`100%` + * - compiler-rt/lib/scudo/standalone/tools + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/stats + - `3` + - `0` + - `3` + - :none:`0%` + * - compiler-rt/lib/tsan/benchmarks + - `6` + - `0` + - `6` + - :none:`0%` + * - compiler-rt/lib/tsan/dd + - `3` + - `0` + - `3` + - :none:`0%` + * - compiler-rt/lib/tsan/go + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/tsan/rtl + - `62` + - `10` + - `52` + - :part:`16%` + * - compiler-rt/lib/tsan/tests/rtl + - `10` + - `1` + - `9` + - :part:`10%` + * - compiler-rt/lib/tsan/tests/unit + - `10` + - `0` + - `10` + - :none:`0%` + * - compiler-rt/lib/ubsan + - `27` + - `7` + - `20` + - :part:`25%` + * - compiler-rt/lib/ubsan_minimal + - `1` + - `0` + - `1` + - :none:`0%` + * - compiler-rt/lib/xray + - `39` + - `30` + - `9` + - :part:`76%` + * - compiler-rt/lib/xray/tests/unit + - `10` + - `8` + - `2` + - :part:`80%` + * - compiler-rt/tools/gwp_asan + - `1` + - `1` + - `0` + - :good:`100%` + * - debuginfo-tests/dexter/feature_tests/commands/penalty + - `6` + - `0` + - `6` + - :none:`0%` + * - debuginfo-tests/dexter/feature_tests/commands/perfect + - `5` + - `0` + - `5` + - :none:`0%` + * - debuginfo-tests/dexter/feature_tests/commands/perfect/expect_step_kind + - `5` + - `0` + - `5` + - :none:`0%` + * - debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps + - `5` + - `0` + - `5` + - :none:`0%` + * - debuginfo-tests/dexter/feature_tests/subtools + - `1` + - `0` + - `1` + - :none:`0%` + * - debuginfo-tests/dexter/feature_tests/subtools/clang-opt-bisect + - `1` + - `0` + - `1` + - :none:`0%` + * - debuginfo-tests/dexter-tests + - `8` + - `3` + - `5` + - :part:`37%` + * - debuginfo-tests/llgdb-tests + - `7` + - `0` + - `7` + - :none:`0%` + * - debuginfo-tests/llvm-prettyprinters/gdb + - `1` + - `1` + - `0` + - :good:`100%` + * - flang/include/flang + - `1` + - `1` + - `0` + - :good:`100%` + * - flang/include/flang/Common + - `19` + - `19` + - `0` + - :good:`100%` + * - flang/include/flang/Decimal + - `2` + - `2` + - `0` + - :good:`100%` + * - flang/include/flang/Evaluate + - `23` + - `23` + - `0` + - :good:`100%` + * - flang/include/flang/Lower + - `13` + - `12` + - `1` + - :part:`92%` + * - flang/include/flang/Lower/Support + - `1` + - `1` + - `0` + - :good:`100%` + * - flang/include/flang/Optimizer/CodeGen + - `1` + - `1` + - `0` + - :good:`100%` + * - flang/include/flang/Optimizer/Dialect + - `5` + - `5` + - `0` + - :good:`100%` + * - flang/include/flang/Optimizer/Support + - `2` + - `2` + - `0` + - :good:`100%` + * - flang/include/flang/Parser + - `17` + - `17` + - `0` + - :good:`100%` + * - flang/include/flang/Semantics + - `8` + - `8` + - `0` + - :good:`100%` + * - flang/lib/Common + - `4` + - `4` + - `0` + - :good:`100%` + * - flang/lib/Decimal + - `3` + - `3` + - `0` + - :good:`100%` + * - flang/lib/Evaluate + - `32` + - `32` + - `0` + - :good:`100%` + * - flang/lib/Lower + - `10` + - `9` + - `1` + - :part:`90%` + * - flang/lib/Optimizer/Dialect + - `4` + - `4` + - `0` + - :good:`100%` + * - flang/lib/Optimizer/Support + - `2` + - `2` + - `0` + - :good:`100%` + * - flang/lib/Parser + - `34` + - `34` + - `0` + - :good:`100%` + * - flang/lib/Semantics + - `68` + - `65` + - `3` + - :part:`95%` + * - flang/module + - `1` + - `0` + - `1` + - :none:`0%` + * - flang/runtime + - `56` + - `56` + - `0` + - :good:`100%` + * - flang/tools/f18 + - `2` + - `2` + - `0` + - :good:`100%` + * - flang/tools/f18-parse-demo + - `2` + - `2` + - `0` + - :good:`100%` + * - flang/tools/tco + - `1` + - `1` + - `0` + - :good:`100%` + * - flang/unittests/Decimal + - `2` + - `2` + - `0` + - :good:`100%` + * - flang/unittests/Evaluate + - `15` + - `15` + - `0` + - :good:`100%` + * - flang/unittests/Optimizer + - `1` + - `1` + - `0` + - :good:`100%` + * - flang/unittests/Runtime + - `7` + - `7` + - `0` + - :good:`100%` + * - libc/AOR_v20.02/math + - `4` + - `1` + - `3` + - :part:`25%` + * - libc/AOR_v20.02/math/include + - `1` + - `0` + - `1` + - :none:`0%` + * - libc/AOR_v20.02/networking + - `1` + - `0` + - `1` + - :none:`0%` + * - libc/AOR_v20.02/networking/include + - `1` + - `0` + - `1` + - :none:`0%` + * - libc/AOR_v20.02/string + - `1` + - `0` + - `1` + - :none:`0%` + * - libc/AOR_v20.02/string/include + - `1` + - `0` + - `1` + - :none:`0%` + * - libc/benchmarks + - `14` + - `14` + - `0` + - :good:`100%` + * - libc/fuzzing/string + - `2` + - `1` + - `1` + - :part:`50%` + * - libc/include + - `4` + - `4` + - `0` + - :good:`100%` + * - libc/loader/linux/x86_64 + - `1` + - `1` + - `0` + - :good:`100%` + * - libc/src/assert + - `2` + - `0` + - `2` + - :none:`0%` + * - libc/src/errno + - `2` + - `2` + - `0` + - :good:`100%` + * - libc/src/math + - `70` + - `70` + - `0` + - :good:`100%` + * - libc/src/signal + - `8` + - `8` + - `0` + - :good:`100%` + * - libc/src/signal/linux + - `10` + - `10` + - `0` + - :good:`100%` + * - libc/src/stdio + - `3` + - `3` + - `0` + - :good:`100%` + * - libc/src/stdlib + - `3` + - `3` + - `0` + - :good:`100%` + * - libc/src/stdlib/linux + - `1` + - `1` + - `0` + - :good:`100%` + * - libc/src/string + - `14` + - `13` + - `1` + - :part:`92%` + * - libc/src/string/memory_utils + - `3` + - `3` + - `0` + - :good:`100%` + * - libc/src/string/x86 + - `1` + - `1` + - `0` + - :good:`100%` + * - libc/src/sys/mman + - `2` + - `2` + - `0` + - :good:`100%` + * - libc/src/sys/mman/linux + - `2` + - `2` + - `0` + - :good:`100%` + * - libc/src/threads + - `6` + - `6` + - `0` + - :good:`100%` + * - libc/src/threads/linux + - `7` + - `7` + - `0` + - :good:`100%` + * - libc/src/unistd + - `1` + - `1` + - `0` + - :good:`100%` + * - libc/src/unistd/linux + - `1` + - `1` + - `0` + - :good:`100%` + * - libc/utils/CPP + - `5` + - `5` + - `0` + - :good:`100%` + * - libc/utils/FPUtil + - `9` + - `9` + - `0` + - :good:`100%` + * - libc/utils/HdrGen + - `9` + - `9` + - `0` + - :good:`100%` + * - libc/utils/HdrGen/PrototypeTestGen + - `1` + - `1` + - `0` + - :good:`100%` + * - libc/utils/MPFRWrapper + - `3` + - `2` + - `1` + - :part:`66%` + * - libc/utils/testutils + - `6` + - `6` + - `0` + - :good:`100%` + * - libc/utils/UnitTest + - `3` + - `3` + - `0` + - :good:`100%` + * - libclc/generic/include + - `2` + - `1` + - `1` + - :part:`50%` + * - libclc/generic/include/clc + - `6` + - `2` + - `4` + - :part:`33%` + * - libclc/generic/include/clc/async + - `4` + - `4` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/atomic + - `11` + - `7` + - `4` + - :part:`63%` + * - libclc/generic/include/clc/cl_khr_global_int32_base_atomics + - `6` + - `5` + - `1` + - :part:`83%` + * - libclc/generic/include/clc/cl_khr_global_int32_extended_atomics + - `5` + - `5` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/cl_khr_int64_base_atomics + - `6` + - `3` + - `3` + - :part:`50%` + * - libclc/generic/include/clc/cl_khr_int64_extended_atomics + - `5` + - `5` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/cl_khr_local_int32_base_atomics + - `6` + - `5` + - `1` + - :part:`83%` + * - libclc/generic/include/clc/cl_khr_local_int32_extended_atomics + - `5` + - `5` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/common + - `6` + - `6` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/explicit_fence + - `1` + - `1` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/float + - `1` + - `0` + - `1` + - :none:`0%` + * - libclc/generic/include/clc/geometric + - `8` + - `8` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/image + - `2` + - `0` + - `2` + - :none:`0%` + * - libclc/generic/include/clc/integer + - `16` + - `13` + - `3` + - :part:`81%` + * - libclc/generic/include/clc/math + - `95` + - `92` + - `3` + - :part:`96%` + * - libclc/generic/include/clc/misc + - `2` + - `0` + - `2` + - :none:`0%` + * - libclc/generic/include/clc/relational + - `18` + - `12` + - `6` + - :part:`66%` + * - libclc/generic/include/clc/shared + - `5` + - `3` + - `2` + - :part:`60%` + * - libclc/generic/include/clc/synchronization + - `2` + - `2` + - `0` + - :good:`100%` + * - libclc/generic/include/clc/workitem + - `8` + - `8` + - `0` + - :good:`100%` + * - libclc/generic/include/integer + - `1` + - `1` + - `0` + - :good:`100%` + * - libclc/generic/include/math + - `15` + - `15` + - `0` + - :good:`100%` + * - libclc/generic/lib + - `1` + - `0` + - `1` + - :none:`0%` + * - libclc/generic/lib/math + - `8` + - `1` + - `7` + - :part:`12%` + * - libclc/generic/lib/relational + - `1` + - `0` + - `1` + - :none:`0%` + * - libclc/utils + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/benchmarks + - `16` + - `1` + - `15` + - :part:`6%` + * - libcxx/fuzzing + - `4` + - `0` + - `4` + - :none:`0%` + * - libcxx/include + - `21` + - `0` + - `21` + - :none:`0%` + * - libcxx/include/support/android + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/include/support/fuchsia + - `1` + - `1` + - `0` + - :good:`100%` + * - libcxx/include/support/ibm + - `4` + - `1` + - `3` + - :part:`25%` + * - libcxx/include/support/musl + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/include/support/newlib + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/include/support/solaris + - `3` + - `2` + - `1` + - :part:`66%` + * - libcxx/include/support/win32 + - `2` + - `0` + - `2` + - :none:`0%` + * - libcxx/include/support/xlocale + - `3` + - `0` + - `3` + - :none:`0%` + * - libcxx/src + - `35` + - `1` + - `34` + - :part:`2%` + * - libcxx/src/experimental + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/src/filesystem + - `4` + - `2` + - `2` + - :part:`50%` + * - libcxx/src/include + - `4` + - `2` + - `2` + - :part:`50%` + * - libcxx/src/support/solaris + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/src/support/win32 + - `3` + - `0` + - `3` + - :none:`0%` + * - libcxx/utils/google-benchmark/cmake + - `5` + - `1` + - `4` + - :part:`20%` + * - libcxx/utils/google-benchmark/include/benchmark + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxx/utils/google-benchmark/src + - `20` + - `16` + - `4` + - :part:`80%` + * - libcxxabi/fuzz + - `1` + - `0` + - `1` + - :none:`0%` + * - libcxxabi/include + - `2` + - `0` + - `2` + - :none:`0%` + * - libcxxabi/src + - `26` + - `1` + - `25` + - :part:`3%` + * - libcxxabi/src/demangle + - `4` + - `2` + - `2` + - :part:`50%` + * - libcxxabi/src/include + - `2` + - `0` + - `2` + - :none:`0%` + * - libunwind/include + - `3` + - `0` + - `3` + - :none:`0%` + * - libunwind/include/mach-o + - `1` + - `0` + - `1` + - :none:`0%` + * - libunwind/src + - `9` + - `0` + - `9` + - :none:`0%` + * - lld/COFF + - `33` + - `10` + - `23` + - :part:`30%` + * - lld/Common + - `10` + - `9` + - `1` + - :part:`90%` + * - lld/ELF + - `48` + - `26` + - `22` + - :part:`54%` + * - lld/ELF/Arch + - `14` + - `7` + - `7` + - :part:`50%` + * - lld/include/lld/Common + - `12` + - `6` + - `6` + - :part:`50%` + * - lld/include/lld/Core + - `20` + - `4` + - `16` + - :part:`20%` + * - lld/include/lld/ReaderWriter + - `2` + - `0` + - `2` + - :none:`0%` + * - lld/lib/Core + - `8` + - `2` + - `6` + - :part:`25%` + * - lld/lib/Driver + - `1` + - `0` + - `1` + - :none:`0%` + * - lld/lib/ReaderWriter + - `1` + - `0` + - `1` + - :none:`0%` + * - lld/lib/ReaderWriter/MachO + - `30` + - `1` + - `29` + - :part:`3%` + * - lld/lib/ReaderWriter/YAML + - `1` + - `0` + - `1` + - :none:`0%` + * - lld/MachO + - `26` + - `26` + - `0` + - :good:`100%` + * - lld/MachO/Arch + - `1` + - `1` + - `0` + - :good:`100%` + * - lld/MinGW + - `1` + - `1` + - `0` + - :good:`100%` + * - lld/tools/lld + - `1` + - `1` + - `0` + - :good:`100%` + * - lld/unittests/DriverTests + - `1` + - `0` + - `1` + - :none:`0%` + * - lld/unittests/MachOTests + - `4` + - `0` + - `4` + - :none:`0%` + * - lld/wasm + - `27` + - `14` + - `13` + - :part:`51%` + * - lldb/examples/darwin/heap_find/heap + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/examples/functions + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/examples/interposing/darwin/fd_interposing + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/examples/lookup + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/examples/plugins/commands + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/examples/synthetic/bitfield + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/include/lldb + - `12` + - `7` + - `5` + - :part:`58%` + * - lldb/include/lldb/API + - `71` + - `59` + - `12` + - :part:`83%` + * - lldb/include/lldb/Breakpoint + - `24` + - `10` + - `14` + - :part:`41%` + * - lldb/include/lldb/Core + - `57` + - `31` + - `26` + - :part:`54%` + * - lldb/include/lldb/DataFormatters + - `18` + - `9` + - `9` + - :part:`50%` + * - lldb/include/lldb/Expression + - `17` + - `6` + - `11` + - :part:`35%` + * - lldb/include/lldb/Host + - `40` + - `20` + - `20` + - :part:`50%` + * - lldb/include/lldb/Host/android + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/include/lldb/Host/common + - `8` + - `2` + - `6` + - :part:`25%` + * - lldb/include/lldb/Host/freebsd + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/include/lldb/Host/linux + - `5` + - `3` + - `2` + - :part:`60%` + * - lldb/include/lldb/Host/macosx + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/include/lldb/Host/netbsd + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/include/lldb/Host/openbsd + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/include/lldb/Host/posix + - `9` + - `7` + - `2` + - :part:`77%` + * - lldb/include/lldb/Host/windows + - `11` + - `5` + - `6` + - :part:`45%` + * - lldb/include/lldb/Initialization + - `3` + - `1` + - `2` + - :part:`33%` + * - lldb/include/lldb/Interpreter + - `47` + - `38` + - `9` + - :part:`80%` + * - lldb/include/lldb/Symbol + - `36` + - `16` + - `20` + - :part:`44%` + * - lldb/include/lldb/Target + - `66` + - `37` + - `29` + - :part:`56%` + * - lldb/include/lldb/Utility + - `58` + - `36` + - `22` + - :part:`62%` + * - lldb/source + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/source/API + - `75` + - `8` + - `67` + - :part:`10%` + * - lldb/source/Breakpoint + - `24` + - `6` + - `18` + - :part:`25%` + * - lldb/source/Commands + - `56` + - `48` + - `8` + - :part:`85%` + * - lldb/source/Core + - `45` + - `24` + - `21` + - :part:`53%` + * - lldb/source/DataFormatters + - `16` + - `3` + - `13` + - :part:`18%` + * - lldb/source/Expression + - `13` + - `4` + - `9` + - :part:`30%` + * - lldb/source/Host/android + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Host/common + - `32` + - `17` + - `15` + - :part:`53%` + * - lldb/source/Host/freebsd + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Host/linux + - `5` + - `3` + - `2` + - :part:`60%` + * - lldb/source/Host/macosx/cfcpp + - `14` + - `12` + - `2` + - :part:`85%` + * - lldb/source/Host/netbsd + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Host/openbsd + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Host/posix + - `9` + - `5` + - `4` + - :part:`55%` + * - lldb/source/Host/windows + - `12` + - `5` + - `7` + - :part:`41%` + * - lldb/source/Initialization + - `3` + - `3` + - `0` + - :good:`100%` + * - lldb/source/Interpreter + - `46` + - `25` + - `21` + - :part:`54%` + * - lldb/source/Plugins/ABI/AArch64 + - `6` + - `2` + - `4` + - :part:`33%` + * - lldb/source/Plugins/ABI/ARC + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ABI/ARM + - `6` + - `4` + - `2` + - :part:`66%` + * - lldb/source/Plugins/ABI/Hexagon + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ABI/Mips + - `6` + - `2` + - `4` + - :part:`33%` + * - lldb/source/Plugins/ABI/PowerPC + - `6` + - `3` + - `3` + - :part:`50%` + * - lldb/source/Plugins/ABI/SystemZ + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ABI/X86 + - `11` + - `4` + - `7` + - :part:`36%` + * - lldb/source/Plugins/Architecture/Arm + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Architecture/Mips + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/Architecture/PPC64 + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/Disassembler/LLVMC + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/DynamicLoader/Darwin-Kernel + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/DynamicLoader/Hexagon-DYLD + - `4` + - `4` + - `0` + - :good:`100%` + * - lldb/source/Plugins/DynamicLoader/MacOSX-DYLD + - `6` + - `3` + - `3` + - :part:`50%` + * - lldb/source/Plugins/DynamicLoader/POSIX-DYLD + - `4` + - `2` + - `2` + - :part:`50%` + * - lldb/source/Plugins/DynamicLoader/Static + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/DynamicLoader/wasm-DYLD + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/DynamicLoader/Windows-DYLD + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/ExpressionParser/Clang + - `51` + - `25` + - `26` + - :part:`49%` + * - lldb/source/Plugins/Instruction/ARM + - `4` + - `2` + - `2` + - :part:`50%` + * - lldb/source/Plugins/Instruction/ARM64 + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/Instruction/MIPS + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/Instruction/MIPS64 + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Instruction/PPC64 + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/InstrumentationRuntime/ASan + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/InstrumentationRuntime/TSan + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/InstrumentationRuntime/UBSan + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/JITLoader/GDB + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Language/ClangCommon + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/Language/CPlusPlus + - `29` + - `17` + - `12` + - :part:`58%` + * - lldb/source/Plugins/Language/ObjC + - `20` + - `13` + - `7` + - :part:`65%` + * - lldb/source/Plugins/Language/ObjCPlusPlus + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/LanguageRuntime/CPlusPlus + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/LanguageRuntime/ObjC + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime + - `16` + - `4` + - `12` + - :part:`25%` + * - lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime + - `8` + - `3` + - `5` + - :part:`37%` + * - lldb/source/Plugins/MemoryHistory/asan + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/ObjectContainer/BSD-Archive + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ObjectContainer/Universal-Mach-O + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/ObjectFile/Breakpad + - `4` + - `3` + - `1` + - :part:`75%` + * - lldb/source/Plugins/ObjectFile/ELF + - `4` + - `1` + - `3` + - :part:`25%` + * - lldb/source/Plugins/ObjectFile/JIT + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ObjectFile/Mach-O + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ObjectFile/PECOFF + - `6` + - `3` + - `3` + - :part:`50%` + * - lldb/source/Plugins/ObjectFile/wasm + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/OperatingSystem/Python + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/Platform/Android + - `6` + - `3` + - `3` + - :part:`50%` + * - lldb/source/Plugins/Platform/FreeBSD + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Platform/gdb-server + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/Platform/Linux + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Platform/MacOSX + - `24` + - `10` + - `14` + - :part:`41%` + * - lldb/source/Plugins/Platform/MacOSX/objcxx + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/source/Plugins/Platform/NetBSD + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Platform/OpenBSD + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Platform/POSIX + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/Platform/Windows + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/Process/elf-core + - `20` + - `18` + - `2` + - :part:`90%` + * - lldb/source/Plugins/Process/FreeBSD + - `19` + - `11` + - `8` + - :part:`57%` + * - lldb/source/Plugins/Process/gdb-remote + - `26` + - `16` + - `10` + - :part:`61%` + * - lldb/source/Plugins/Process/Linux + - `24` + - `12` + - `12` + - :part:`50%` + * - lldb/source/Plugins/Process/mach-core + - `4` + - `3` + - `1` + - :part:`75%` + * - lldb/source/Plugins/Process/MacOSX-Kernel + - `16` + - `13` + - `3` + - :part:`81%` + * - lldb/source/Plugins/Process/minidump + - `17` + - `10` + - `7` + - :part:`58%` + * - lldb/source/Plugins/Process/NetBSD + - `8` + - `3` + - `5` + - :part:`37%` + * - lldb/source/Plugins/Process/POSIX + - `8` + - `5` + - `3` + - :part:`62%` + * - lldb/source/Plugins/Process/Utility + - `127` + - `86` + - `41` + - :part:`67%` + * - lldb/source/Plugins/Process/Windows/Common + - `34` + - `24` + - `10` + - :part:`70%` + * - lldb/source/Plugins/Process/Windows/Common/arm + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Process/Windows/Common/arm64 + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/Process/Windows/Common/x64 + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/Process/Windows/Common/x86 + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/ScriptInterpreter/Lua + - `4` + - `4` + - `0` + - :good:`100%` + * - lldb/source/Plugins/ScriptInterpreter/None + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/ScriptInterpreter/Python + - `8` + - `3` + - `5` + - :part:`37%` + * - lldb/source/Plugins/StructuredData/DarwinLog + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/SymbolFile/Breakpad + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/SymbolFile/DWARF + - `65` + - `35` + - `30` + - :part:`53%` + * - lldb/source/Plugins/SymbolFile/NativePDB + - `20` + - `11` + - `9` + - :part:`55%` + * - lldb/source/Plugins/SymbolFile/PDB + - `6` + - `4` + - `2` + - :part:`66%` + * - lldb/source/Plugins/SymbolFile/Symtab + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/SymbolVendor/ELF + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/SymbolVendor/MacOSX + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/SymbolVendor/wasm + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/source/Plugins/SystemRuntime/MacOSX + - `10` + - `1` + - `9` + - :part:`10%` + * - lldb/source/Plugins/TypeSystem/Clang + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/source/Plugins/UnwindAssembly/InstEmulation + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/source/Plugins/UnwindAssembly/x86 + - `4` + - `2` + - `2` + - :part:`50%` + * - lldb/source/Symbol + - `32` + - `18` + - `14` + - :part:`56%` + * - lldb/source/Target + - `61` + - `28` + - `33` + - :part:`45%` + * - lldb/source/Utility + - `54` + - `41` + - `13` + - :part:`75%` + * - lldb/tools/argdumper + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/tools/darwin-debug + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/tools/debugserver/source + - `49` + - `38` + - `11` + - :part:`77%` + * - lldb/tools/debugserver/source/MacOSX + - `24` + - `16` + - `8` + - :part:`66%` + * - lldb/tools/debugserver/source/MacOSX/arm + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/tools/debugserver/source/MacOSX/arm64 + - `2` + - `1` + - `1` + - :part:`50%` + * - lldb/tools/debugserver/source/MacOSX/DarwinLog + - `20` + - `18` + - `2` + - :part:`90%` + * - lldb/tools/debugserver/source/MacOSX/i386 + - `3` + - `1` + - `2` + - :part:`33%` + * - lldb/tools/debugserver/source/MacOSX/x86_64 + - `3` + - `1` + - `2` + - :part:`33%` + * - lldb/tools/driver + - `4` + - `4` + - `0` + - :good:`100%` + * - lldb/tools/intel-features + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/tools/intel-features/intel-mpx + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/tools/intel-features/intel-pt + - `6` + - `6` + - `0` + - :good:`100%` + * - lldb/tools/lldb-instr + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/tools/lldb-server + - `9` + - `4` + - `5` + - :part:`44%` + * - lldb/tools/lldb-test + - `5` + - `3` + - `2` + - :part:`60%` + * - lldb/tools/lldb-vscode + - `19` + - `12` + - `7` + - :part:`63%` + * - lldb/unittests + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/API + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Breakpoint + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Core + - `6` + - `5` + - `1` + - :part:`83%` + * - lldb/unittests/DataFormatter + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/unittests/debugserver + - `3` + - `2` + - `1` + - :part:`66%` + * - lldb/unittests/Disassembler + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/unittests/Editline + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Expression + - `5` + - `3` + - `2` + - :part:`60%` + * - lldb/unittests/Host + - `13` + - `10` + - `3` + - :part:`76%` + * - lldb/unittests/Host/linux + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/unittests/Instruction + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/Interpreter + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/unittests/Language/CLanguages + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Language/CPlusPlus + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/Language/Highlighting + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/ObjectFile/Breakpad + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/ObjectFile/ELF + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/ObjectFile/PECOFF + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/Platform + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Platform/Android + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/Process + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Process/gdb-remote + - `6` + - `5` + - `1` + - :part:`83%` + * - lldb/unittests/Process/Linux + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/Process/minidump + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/unittests/Process/minidump/Inputs + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Process/POSIX + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/ScriptInterpreter/Lua + - `2` + - `2` + - `0` + - :good:`100%` + * - lldb/unittests/ScriptInterpreter/Python + - `3` + - `1` + - `2` + - :part:`33%` + * - lldb/unittests/Signals + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/Symbol + - `7` + - `4` + - `3` + - :part:`57%` + * - lldb/unittests/SymbolFile/DWARF + - `3` + - `0` + - `3` + - :none:`0%` + * - lldb/unittests/SymbolFile/DWARF/Inputs + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/SymbolFile/NativePDB + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/SymbolFile/PDB + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/SymbolFile/PDB/Inputs + - `5` + - `5` + - `0` + - :good:`100%` + * - lldb/unittests/Target + - `7` + - `3` + - `4` + - :part:`42%` + * - lldb/unittests/TestingSupport + - `5` + - `4` + - `1` + - :part:`80%` + * - lldb/unittests/TestingSupport/Host + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/TestingSupport/Symbol + - `3` + - `3` + - `0` + - :good:`100%` + * - lldb/unittests/Thread + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/tools/lldb-server/inferior + - `2` + - `0` + - `2` + - :none:`0%` + * - lldb/unittests/tools/lldb-server/tests + - `8` + - `1` + - `7` + - :part:`12%` + * - lldb/unittests/UnwindAssembly/ARM64 + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/UnwindAssembly/PPC64 + - `1` + - `1` + - `0` + - :good:`100%` + * - lldb/unittests/UnwindAssembly/x86 + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/unittests/Utility + - `44` + - `32` + - `12` + - :part:`72%` + * - lldb/utils/lit-cpuid + - `1` + - `0` + - `1` + - :none:`0%` + * - lldb/utils/TableGen + - `6` + - `6` + - `0` + - :good:`100%` + * - llvm/benchmarks + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/bindings/go/llvm + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/cmake + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/BrainF + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/examples/Bye + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/ExceptionDemo + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Fibonacci + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/HowToUseJIT + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/HowToUseLLJIT + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/IRTransforms + - `4` + - `4` + - `0` + - :good:`100%` + * - llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1 + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2 + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/examples/Kaleidoscope/BuildingAJIT/Chapter3 + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4 + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5 + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter2 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter3 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter4 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter5 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter6 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter7 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter8 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/Chapter9 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/include + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/Kaleidoscope/MCJIT/cached + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/examples/Kaleidoscope/MCJIT/complete + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/MCJIT/initial + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/Kaleidoscope/MCJIT/lazy + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/examples/ModuleMaker + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/OrcV2Examples + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITDumpObjects + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITWithCustomObjectLinkingLayer + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITWithGDBRegistrationListener + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITWithInitializers + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITWithLazyReexports + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITWithObjectCache + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/examples/ParallelJIT + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/SpeculativeJIT + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/examples/ThinLtoJIT + - `9` + - `8` + - `1` + - :part:`88%` + * - llvm/include/llvm + - `8` + - `2` + - `6` + - :part:`25%` + * - llvm/include/llvm/ADT + - `84` + - `24` + - `60` + - :part:`28%` + * - llvm/include/llvm/Analysis + - `113` + - `34` + - `79` + - :part:`30%` + * - llvm/include/llvm/Analysis/Utils + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/AsmParser + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/include/llvm/BinaryFormat + - `13` + - `9` + - `4` + - :part:`69%` + * - llvm/include/llvm/Bitcode + - `5` + - `1` + - `4` + - :part:`20%` + * - llvm/include/llvm/Bitstream + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/include/llvm/CodeGen + - `141` + - `32` + - `109` + - :part:`22%` + * - llvm/include/llvm/CodeGen/GlobalISel + - `27` + - `10` + - `17` + - :part:`37%` + * - llvm/include/llvm/CodeGen/MIRParser + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/include/llvm/CodeGen/PBQP + - `5` + - `1` + - `4` + - :part:`20%` + * - llvm/include/llvm/DebugInfo + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/DebugInfo/CodeView + - `57` + - `40` + - `17` + - :part:`70%` + * - llvm/include/llvm/DebugInfo/DWARF + - `32` + - `17` + - `15` + - :part:`53%` + * - llvm/include/llvm/DebugInfo/GSYM + - `14` + - `2` + - `12` + - :part:`14%` + * - llvm/include/llvm/DebugInfo/MSF + - `5` + - `4` + - `1` + - :part:`80%` + * - llvm/include/llvm/DebugInfo/PDB + - `50` + - `7` + - `43` + - :part:`14%` + * - llvm/include/llvm/DebugInfo/PDB/DIA + - `20` + - `9` + - `11` + - :part:`45%` + * - llvm/include/llvm/DebugInfo/PDB/Native + - `52` + - `34` + - `18` + - :part:`65%` + * - llvm/include/llvm/DebugInfo/Symbolize + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/include/llvm/Demangle + - `7` + - `3` + - `4` + - :part:`42%` + * - llvm/include/llvm/DWARFLinker + - `4` + - `4` + - `0` + - :good:`100%` + * - llvm/include/llvm/ExecutionEngine + - `14` + - `3` + - `11` + - :part:`21%` + * - llvm/include/llvm/ExecutionEngine/JITLink + - `8` + - `5` + - `3` + - :part:`62%` + * - llvm/include/llvm/ExecutionEngine/Orc + - `32` + - `11` + - `21` + - :part:`34%` + * - llvm/include/llvm/ExecutionEngine/Orc/RPC + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/include/llvm/Frontend/OpenMP + - `4` + - `4` + - `0` + - :good:`100%` + * - llvm/include/llvm/FuzzMutate + - `6` + - `0` + - `6` + - :none:`0%` + * - llvm/include/llvm/IR + - `84` + - `15` + - `69` + - :part:`17%` + * - llvm/include/llvm/IRReader + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/LineEditor + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/Linker + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/include/llvm/LTO + - `5` + - `2` + - `3` + - :part:`40%` + * - llvm/include/llvm/LTO/legacy + - `4` + - `0` + - `4` + - :none:`0%` + * - llvm/include/llvm/MC + - `69` + - `17` + - `52` + - :part:`24%` + * - llvm/include/llvm/MC/MCDisassembler + - `4` + - `1` + - `3` + - :part:`25%` + * - llvm/include/llvm/MC/MCParser + - `8` + - `3` + - `5` + - :part:`37%` + * - llvm/include/llvm/MCA + - `8` + - `8` + - `0` + - :good:`100%` + * - llvm/include/llvm/MCA/HardwareUnits + - `6` + - `4` + - `2` + - :part:`66%` + * - llvm/include/llvm/MCA/Stages + - `7` + - `6` + - `1` + - :part:`85%` + * - llvm/include/llvm/Object + - `30` + - `10` + - `20` + - :part:`33%` + * - llvm/include/llvm/ObjectYAML + - `15` + - `13` + - `2` + - :part:`86%` + * - llvm/include/llvm/Option + - `5` + - `1` + - `4` + - :part:`20%` + * - llvm/include/llvm/Passes + - `3` + - `1` + - `2` + - :part:`33%` + * - llvm/include/llvm/ProfileData + - `8` + - `4` + - `4` + - :part:`50%` + * - llvm/include/llvm/ProfileData/Coverage + - `3` + - `2` + - `1` + - :part:`66%` + * - llvm/include/llvm/Remarks + - `11` + - `10` + - `1` + - :part:`90%` + * - llvm/include/llvm/Support + - `170` + - `50` + - `120` + - :part:`29%` + * - llvm/include/llvm/Support/Solaris/sys + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/include/llvm/Support/Windows + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/TableGen + - `7` + - `1` + - `6` + - :part:`14%` + * - llvm/include/llvm/Target + - `5` + - `1` + - `4` + - :part:`20%` + * - llvm/include/llvm/Testing/Support + - `3` + - `2` + - `1` + - :part:`66%` + * - llvm/include/llvm/TextAPI/ELF + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/include/llvm/TextAPI/MachO + - `9` + - `8` + - `1` + - :part:`88%` + * - llvm/include/llvm/ToolDrivers/llvm-dlltool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/include/llvm/ToolDrivers/llvm-lib + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/Transforms + - `8` + - `2` + - `6` + - :part:`25%` + * - llvm/include/llvm/Transforms/AggressiveInstCombine + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/include/llvm/Transforms/Coroutines + - `4` + - `4` + - `0` + - :good:`100%` + * - llvm/include/llvm/Transforms/InstCombine + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/include/llvm/Transforms/Instrumentation + - `14` + - `8` + - `6` + - :part:`57%` + * - llvm/include/llvm/Transforms/IPO + - `29` + - `19` + - `10` + - :part:`65%` + * - llvm/include/llvm/Transforms/Scalar + - `61` + - `32` + - `29` + - :part:`52%` + * - llvm/include/llvm/Transforms/Utils + - `57` + - `26` + - `31` + - :part:`45%` + * - llvm/include/llvm/Transforms/Vectorize + - `5` + - `1` + - `4` + - :part:`20%` + * - llvm/include/llvm/WindowsManifest + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/include/llvm/WindowsResource + - `3` + - `1` + - `2` + - :part:`33%` + * - llvm/include/llvm/XRay + - `17` + - `14` + - `3` + - :part:`82%` + * - llvm/include/llvm-c + - `26` + - `11` + - `15` + - :part:`42%` + * - llvm/include/llvm-c/Transforms + - `8` + - `2` + - `6` + - :part:`25%` + * - llvm/lib/Analysis + - `109` + - `33` + - `76` + - :part:`30%` + * - llvm/lib/AsmParser + - `6` + - `2` + - `4` + - :part:`33%` + * - llvm/lib/BinaryFormat + - `11` + - `7` + - `4` + - :part:`63%` + * - llvm/lib/Bitcode/Reader + - `7` + - `2` + - `5` + - :part:`28%` + * - llvm/lib/Bitcode/Writer + - `5` + - `0` + - `5` + - :none:`0%` + * - llvm/lib/Bitstream/Reader + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/CodeGen + - `196` + - `31` + - `165` + - :part:`15%` + * - llvm/lib/CodeGen/AsmPrinter + - `42` + - `14` + - `28` + - :part:`33%` + * - llvm/lib/CodeGen/GlobalISel + - `24` + - `8` + - `16` + - :part:`33%` + * - llvm/lib/CodeGen/MIRParser + - `4` + - `1` + - `3` + - :part:`25%` + * - llvm/lib/CodeGen/SelectionDAG + - `31` + - `2` + - `29` + - :part:`6%` + * - llvm/lib/DebugInfo/CodeView + - `40` + - `25` + - `15` + - :part:`62%` + * - llvm/lib/DebugInfo/DWARF + - `28` + - `7` + - `21` + - :part:`25%` + * - llvm/lib/DebugInfo/GSYM + - `11` + - `1` + - `10` + - :part:`9%` + * - llvm/lib/DebugInfo/MSF + - `4` + - `4` + - `0` + - :good:`100%` + * - llvm/lib/DebugInfo/PDB + - `40` + - `34` + - `6` + - :part:`85%` + * - llvm/lib/DebugInfo/PDB/DIA + - `18` + - `15` + - `3` + - :part:`83%` + * - llvm/lib/DebugInfo/PDB/Native + - `48` + - `36` + - `12` + - :part:`75%` + * - llvm/lib/DebugInfo/Symbolize + - `4` + - `1` + - `3` + - :part:`25%` + * - llvm/lib/Demangle + - `4` + - `2` + - `2` + - :part:`50%` + * - llvm/lib/DWARFLinker + - `4` + - `3` + - `1` + - :part:`75%` + * - llvm/lib/ExecutionEngine + - `5` + - `1` + - `4` + - :part:`20%` + * - llvm/lib/ExecutionEngine/IntelJITEvents + - `5` + - `0` + - `5` + - :none:`0%` + * - llvm/lib/ExecutionEngine/Interpreter + - `4` + - `0` + - `4` + - :none:`0%` + * - llvm/lib/ExecutionEngine/JITLink + - `14` + - `9` + - `5` + - :part:`64%` + * - llvm/lib/ExecutionEngine/MCJIT + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/ExecutionEngine/OProfileJIT + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/ExecutionEngine/Orc + - `28` + - `15` + - `13` + - :part:`53%` + * - llvm/lib/ExecutionEngine/OrcError + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/ExecutionEngine/PerfJITEvents + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/ExecutionEngine/RuntimeDyld + - `12` + - `1` + - `11` + - :part:`8%` + * - llvm/lib/ExecutionEngine/RuntimeDyld/Targets + - `10` + - `1` + - `9` + - :part:`10%` + * - llvm/lib/Extensions + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/lib/Frontend/OpenMP + - `3` + - `2` + - `1` + - :part:`66%` + * - llvm/lib/FuzzMutate + - `5` + - `2` + - `3` + - :part:`40%` + * - llvm/lib/IR + - `61` + - `11` + - `50` + - :part:`18%` + * - llvm/lib/IRReader + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/LineEditor + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Linker + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/lib/LTO + - `8` + - `1` + - `7` + - :part:`12%` + * - llvm/lib/MC + - `62` + - `20` + - `42` + - :part:`32%` + * - llvm/lib/MC/MCDisassembler + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/lib/MC/MCParser + - `12` + - `1` + - `11` + - :part:`8%` + * - llvm/lib/MCA + - `7` + - `3` + - `4` + - :part:`42%` + * - llvm/lib/MCA/HardwareUnits + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/lib/MCA/Stages + - `7` + - `6` + - `1` + - :part:`85%` + * - llvm/lib/Object + - `29` + - `10` + - `19` + - :part:`34%` + * - llvm/lib/ObjectYAML + - `22` + - `13` + - `9` + - :part:`59%` + * - llvm/lib/Option + - `4` + - `0` + - `4` + - :none:`0%` + * - llvm/lib/Passes + - `3` + - `2` + - `1` + - :part:`66%` + * - llvm/lib/ProfileData + - `8` + - `2` + - `6` + - :part:`25%` + * - llvm/lib/ProfileData/Coverage + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/lib/Remarks + - `13` + - `10` + - `3` + - :part:`76%` + * - llvm/lib/Support + - `132` + - `44` + - `88` + - :part:`33%` + * - llvm/lib/Support/Unix + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/TableGen + - `11` + - `1` + - `10` + - :part:`9%` + * - llvm/lib/Target + - `5` + - `0` + - `5` + - :none:`0%` + * - llvm/lib/Target/AArch64 + - `59` + - `7` + - `52` + - :part:`11%` + * - llvm/lib/Target/AArch64/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/AArch64/Disassembler + - `4` + - `1` + - `3` + - :part:`25%` + * - llvm/lib/Target/AArch64/GISel + - `9` + - `0` + - `9` + - :none:`0%` + * - llvm/lib/Target/AArch64/MCTargetDesc + - `21` + - `6` + - `15` + - :part:`28%` + * - llvm/lib/Target/AArch64/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/AArch64/Utils + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/Target/AMDGPU + - `146` + - `12` + - `134` + - :part:`8%` + * - llvm/lib/Target/AMDGPU/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/AMDGPU/Disassembler + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/Target/AMDGPU/MCTargetDesc + - `18` + - `3` + - `15` + - :part:`16%` + * - llvm/lib/Target/AMDGPU/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/AMDGPU/Utils + - `9` + - `2` + - `7` + - :part:`22%` + * - llvm/lib/Target/ARC + - `24` + - `19` + - `5` + - :part:`79%` + * - llvm/lib/Target/ARC/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/ARC/MCTargetDesc + - `7` + - `6` + - `1` + - :part:`85%` + * - llvm/lib/Target/ARC/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/ARM + - `71` + - `7` + - `64` + - :part:`9%` + * - llvm/lib/Target/ARM/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/ARM/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/ARM/MCTargetDesc + - `26` + - `2` + - `24` + - :part:`7%` + * - llvm/lib/Target/ARM/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/ARM/Utils + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/Target/AVR + - `23` + - `4` + - `19` + - :part:`17%` + * - llvm/lib/Target/AVR/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/AVR/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/AVR/MCTargetDesc + - `20` + - `6` + - `14` + - :part:`30%` + * - llvm/lib/Target/AVR/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/BPF + - `28` + - `5` + - `23` + - :part:`17%` + * - llvm/lib/Target/BPF/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/BPF/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/BPF/MCTargetDesc + - `8` + - `1` + - `7` + - :part:`12%` + * - llvm/lib/Target/BPF/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/Hexagon + - `77` + - `2` + - `75` + - :part:`2%` + * - llvm/lib/Target/Hexagon/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Hexagon/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Hexagon/MCTargetDesc + - `26` + - `6` + - `20` + - :part:`23%` + * - llvm/lib/Target/Hexagon/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/Lanai + - `28` + - `19` + - `9` + - :part:`67%` + * - llvm/lib/Target/Lanai/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Lanai/Disassembler + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/Lanai/MCTargetDesc + - `13` + - `12` + - `1` + - :part:`92%` + * - llvm/lib/Target/Lanai/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/Mips + - `69` + - `12` + - `57` + - :part:`17%` + * - llvm/lib/Target/Mips/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Mips/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Mips/MCTargetDesc + - `25` + - `6` + - `19` + - :part:`24%` + * - llvm/lib/Target/Mips/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/MSP430 + - `20` + - `0` + - `20` + - :none:`0%` + * - llvm/lib/Target/MSP430/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/MSP430/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/MSP430/MCTargetDesc + - `11` + - `3` + - `8` + - :part:`27%` + * - llvm/lib/Target/MSP430/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/NVPTX + - `42` + - `7` + - `35` + - :part:`16%` + * - llvm/lib/Target/NVPTX/MCTargetDesc + - `9` + - `5` + - `4` + - :part:`55%` + * - llvm/lib/Target/NVPTX/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/PowerPC + - `53` + - `2` + - `51` + - :part:`3%` + * - llvm/lib/Target/PowerPC/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/PowerPC/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/PowerPC/MCTargetDesc + - `18` + - `2` + - `16` + - :part:`11%` + * - llvm/lib/Target/PowerPC/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/RISCV + - `31` + - `13` + - `18` + - :part:`41%` + * - llvm/lib/Target/RISCV/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/RISCV/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/RISCV/MCTargetDesc + - `17` + - `8` + - `9` + - :part:`47%` + * - llvm/lib/Target/RISCV/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/RISCV/Utils + - `4` + - `3` + - `1` + - :part:`75%` + * - llvm/lib/Target/Sparc + - `23` + - `2` + - `21` + - :part:`8%` + * - llvm/lib/Target/Sparc/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Sparc/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/Sparc/MCTargetDesc + - `14` + - `4` + - `10` + - :part:`28%` + * - llvm/lib/Target/Sparc/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/SystemZ + - `40` + - `4` + - `36` + - :part:`10%` + * - llvm/lib/Target/SystemZ/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/SystemZ/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/SystemZ/MCTargetDesc + - `10` + - `4` + - `6` + - :part:`40%` + * - llvm/lib/Target/SystemZ/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/VE + - `19` + - `15` + - `4` + - :part:`78%` + * - llvm/lib/Target/VE/AsmParser + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/lib/Target/VE/Disassembler + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/lib/Target/VE/MCTargetDesc + - `14` + - `13` + - `1` + - :part:`92%` + * - llvm/lib/Target/VE/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/WebAssembly + - `58` + - `40` + - `18` + - :part:`68%` + * - llvm/lib/Target/WebAssembly/AsmParser + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/WebAssembly/Disassembler + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/lib/Target/WebAssembly/MCTargetDesc + - `12` + - `7` + - `5` + - :part:`58%` + * - llvm/lib/Target/WebAssembly/TargetInfo + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/lib/Target/X86 + - `75` + - `11` + - `64` + - :part:`14%` + * - llvm/lib/Target/X86/AsmParser + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/lib/Target/X86/Disassembler + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/lib/Target/X86/MCTargetDesc + - `25` + - `6` + - `19` + - :part:`24%` + * - llvm/lib/Target/X86/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Target/XCore + - `27` + - `2` + - `25` + - :part:`7%` + * - llvm/lib/Target/XCore/Disassembler + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Target/XCore/MCTargetDesc + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/lib/Target/XCore/TargetInfo + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/Testing/Support + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/lib/TextAPI/ELF + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/lib/TextAPI/MachO + - `11` + - `8` + - `3` + - :part:`72%` + * - llvm/lib/ToolDrivers/llvm-dlltool + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/ToolDrivers/llvm-lib + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Transforms/AggressiveInstCombine + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/lib/Transforms/CFGuard + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/lib/Transforms/Coroutines + - `8` + - `0` + - `8` + - :none:`0%` + * - llvm/lib/Transforms/Hello + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/lib/Transforms/InstCombine + - `16` + - `1` + - `15` + - :part:`6%` + * - llvm/lib/Transforms/Instrumentation + - `21` + - `3` + - `18` + - :part:`14%` + * - llvm/lib/Transforms/IPO + - `39` + - `5` + - `34` + - :part:`12%` + * - llvm/lib/Transforms/ObjCARC + - `15` + - `3` + - `12` + - :part:`20%` + * - llvm/lib/Transforms/Scalar + - `75` + - `10` + - `65` + - :part:`13%` + * - llvm/lib/Transforms/Utils + - `72` + - `14` + - `58` + - :part:`19%` + * - llvm/lib/Transforms/Vectorize + - `22` + - `14` + - `8` + - :part:`63%` + * - llvm/lib/WindowsManifest + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/lib/XRay + - `14` + - `12` + - `2` + - :part:`85%` + * - llvm/tools/bugpoint + - `12` + - `1` + - `11` + - :part:`8%` + * - llvm/tools/bugpoint-passes + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/dsymutil + - `18` + - `15` + - `3` + - :part:`83%` + * - llvm/tools/gold + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llc + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/lli + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/tools/lli/ChildTarget + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-ar + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-as + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-as-fuzzer + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-bcanalyzer + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-c-test + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/tools/llvm-cat + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-cfi-verify + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-cfi-verify/lib + - `4` + - `1` + - `3` + - :part:`25%` + * - llvm/tools/llvm-config + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-cov + - `23` + - `12` + - `11` + - :part:`52%` + * - llvm/tools/llvm-cvtres + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-cxxdump + - `4` + - `2` + - `2` + - :part:`50%` + * - llvm/tools/llvm-cxxfilt + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-cxxmap + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-diff + - `7` + - `0` + - `7` + - :none:`0%` + * - llvm/tools/llvm-dis + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-dwarfdump + - `4` + - `2` + - `2` + - :part:`50%` + * - llvm/tools/llvm-dwarfdump/fuzzer + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-dwp + - `4` + - `1` + - `3` + - :part:`25%` + * - llvm/tools/llvm-elfabi + - `5` + - `2` + - `3` + - :part:`40%` + * - llvm/tools/llvm-exegesis + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-exegesis/lib + - `44` + - `35` + - `9` + - :part:`79%` + * - llvm/tools/llvm-exegesis/lib/AArch64 + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-exegesis/lib/Mips + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-exegesis/lib/PowerPC + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-exegesis/lib/X86 + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-extract + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-gsymutil + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-ifs + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-isel-fuzzer + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/tools/llvm-itanium-demangle-fuzzer + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/tools/llvm-jitlink + - `4` + - `2` + - `2` + - :part:`50%` + * - llvm/tools/llvm-jitlistener + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-link + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-lipo + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-lto + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-lto2 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-mc + - `3` + - `1` + - `2` + - :part:`33%` + * - llvm/tools/llvm-mc-assemble-fuzzer + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-mc-disassemble-fuzzer + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-mca + - `7` + - `6` + - `1` + - :part:`85%` + * - llvm/tools/llvm-mca/Views + - `20` + - `15` + - `5` + - :part:`75%` + * - llvm/tools/llvm-microsoft-demangle-fuzzer + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/tools/llvm-ml + - `3` + - `1` + - `2` + - :part:`33%` + * - llvm/tools/llvm-modextract + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-mt + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-nm + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-objcopy + - `6` + - `4` + - `2` + - :part:`66%` + * - llvm/tools/llvm-objcopy/COFF + - `8` + - `7` + - `1` + - :part:`87%` + * - llvm/tools/llvm-objcopy/ELF + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/tools/llvm-objcopy/MachO + - `10` + - `10` + - `0` + - :good:`100%` + * - llvm/tools/llvm-objcopy/wasm + - `8` + - `8` + - `0` + - :good:`100%` + * - llvm/tools/llvm-objdump + - `12` + - `8` + - `4` + - :part:`66%` + * - llvm/tools/llvm-opt-fuzzer + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/tools/llvm-opt-report + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-pdbutil + - `47` + - `16` + - `31` + - :part:`34%` + * - llvm/tools/llvm-profdata + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-rc + - `12` + - `7` + - `5` + - :part:`58%` + * - llvm/tools/llvm-readobj + - `21` + - `3` + - `18` + - :part:`14%` + * - llvm/tools/llvm-reduce + - `4` + - `2` + - `2` + - :part:`50%` + * - llvm/tools/llvm-reduce/deltas + - `14` + - `8` + - `6` + - :part:`57%` + * - llvm/tools/llvm-rtdyld + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-shlib + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-size + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-special-case-list-fuzzer + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/tools/llvm-split + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-stress + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-strings + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-symbolizer + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/llvm-undname + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/llvm-xray + - `19` + - `16` + - `3` + - :part:`84%` + * - llvm/tools/llvm-yaml-numeric-parser-fuzzer + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/tools/lto + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/tools/obj2yaml + - `11` + - `4` + - `7` + - :part:`36%` + * - llvm/tools/opt + - `10` + - `2` + - `8` + - :part:`20%` + * - llvm/tools/remarks-shlib + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/sancov + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/sanstats + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/verify-uselistorder + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/tools/vfabi-demangle-fuzzer + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/tools/yaml2obj + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/ADT + - `74` + - `29` + - `45` + - :part:`39%` + * - llvm/unittests/Analysis + - `34` + - `11` + - `23` + - :part:`32%` + * - llvm/unittests/AsmParser + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/BinaryFormat + - `6` + - `5` + - `1` + - :part:`83%` + * - llvm/unittests/Bitcode + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/unittests/Bitstream + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/unittests/CodeGen + - `10` + - `2` + - `8` + - :part:`20%` + * - llvm/unittests/CodeGen/GlobalISel + - `11` + - `1` + - `10` + - :part:`9%` + * - llvm/unittests/DebugInfo/CodeView + - `3` + - `1` + - `2` + - :part:`33%` + * - llvm/unittests/DebugInfo/DWARF + - `13` + - `8` + - `5` + - :part:`61%` + * - llvm/unittests/DebugInfo/GSYM + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/DebugInfo/MSF + - `3` + - `2` + - `1` + - :part:`66%` + * - llvm/unittests/DebugInfo/PDB + - `5` + - `3` + - `2` + - :part:`60%` + * - llvm/unittests/DebugInfo/PDB/Inputs + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/Demangle + - `3` + - `2` + - `1` + - :part:`66%` + * - llvm/unittests/ExecutionEngine + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/ExecutionEngine/JITLink + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/ExecutionEngine/MCJIT + - `7` + - `0` + - `7` + - :none:`0%` + * - llvm/unittests/ExecutionEngine/Orc + - `20` + - `4` + - `16` + - :part:`20%` + * - llvm/unittests/Frontend + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/unittests/FuzzMutate + - `4` + - `0` + - `4` + - :none:`0%` + * - llvm/unittests/IR + - `35` + - `7` + - `28` + - :part:`20%` + * - llvm/unittests/LineEditor + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/Linker + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/MC + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/unittests/MC/AMDGPU + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/MI + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/Object + - `8` + - `7` + - `1` + - :part:`87%` + * - llvm/unittests/ObjectYAML + - `4` + - `2` + - `2` + - :part:`50%` + * - llvm/unittests/Option + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/Passes + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/unittests/ProfileData + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/unittests/Remarks + - `8` + - `5` + - `3` + - :part:`62%` + * - llvm/unittests/Support + - `89` + - `24` + - `65` + - :part:`26%` + * - llvm/unittests/Support/DynamicLibrary + - `4` + - `0` + - `4` + - :none:`0%` + * - llvm/unittests/TableGen + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/unittests/Target/AArch64 + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/unittests/Target/AMDGPU + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/Target/ARM + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/Target/PowerPC + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/Target/WebAssembly + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/Target/X86 + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/unittests/TextAPI + - `6` + - `3` + - `3` + - :part:`50%` + * - llvm/unittests/tools/llvm-cfi-verify + - `2` + - `1` + - `1` + - :part:`50%` + * - llvm/unittests/tools/llvm-exegesis + - `5` + - `4` + - `1` + - :part:`80%` + * - llvm/unittests/tools/llvm-exegesis/AArch64 + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/tools/llvm-exegesis/ARM + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/tools/llvm-exegesis/Common + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/unittests/tools/llvm-exegesis/Mips + - `5` + - `4` + - `1` + - :part:`80%` + * - llvm/unittests/tools/llvm-exegesis/PowerPC + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/unittests/tools/llvm-exegesis/X86 + - `9` + - `8` + - `1` + - :part:`88%` + * - llvm/unittests/Transforms/IPO + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/unittests/Transforms/Scalar + - `2` + - `0` + - `2` + - :none:`0%` + * - llvm/unittests/Transforms/Utils + - `17` + - `7` + - `10` + - :part:`41%` + * - llvm/unittests/Transforms/Vectorize + - `7` + - `7` + - `0` + - :good:`100%` + * - llvm/unittests/XRay + - `8` + - `7` + - `1` + - :part:`87%` + * - llvm/utils/benchmark/cmake + - `5` + - `3` + - `2` + - :part:`60%` + * - llvm/utils/benchmark/include/benchmark + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/benchmark/src + - `19` + - `0` + - `19` + - :none:`0%` + * - llvm/utils/FileCheck + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/fpcmp + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/KillTheDoctor + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/not + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/PerfectShuffle + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/change-namespace + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/change-namespace/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-apply-replacements/include/clang-apply-replacements/Tooling + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-apply-replacements/lib/Tooling + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-apply-replacements/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-doc + - `16` + - `16` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-doc/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-move + - `4` + - `4` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-move/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-query + - `5` + - `5` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-query/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-reorder-fields + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-reorder-fields/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy + - `12` + - `12` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/abseil + - `36` + - `36` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/android + - `29` + - `29` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/boost + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/bugprone + - `81` + - `81` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/cert + - `23` + - `23` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/cppcoreguidelines + - `37` + - `37` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/fuchsia + - `15` + - `15` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/google + - `31` + - `31` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/hicpp + - `9` + - `9` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/llvm + - `7` + - `7` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/misc + - `27` + - `27` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/modernize + - `63` + - `63` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/mpi + - `5` + - `5` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/objc + - `9` + - `9` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/performance + - `25` + - `25` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/plugin + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/portability + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/readability + - `67` + - `67` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/utils + - `29` + - `29` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clang-tidy/zircon + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd + - `66` + - `66` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/benchmarks + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/fuzzer + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/index + - `30` + - `30` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/index/dex + - `9` + - `9` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/index/dex/dexp + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/indexer + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/refactor + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/refactor/tweaks + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/xpc + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/xpc/framework + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/clangd/xpc/test-client + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/include-fixer + - `13` + - `13` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/include-fixer/find-all-symbols + - `17` + - `17` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/include-fixer/find-all-symbols/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/include-fixer/plugin + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/include-fixer/tool + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/modularize + - `9` + - `9` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/pp-trace + - `3` + - `3` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/tool-template + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/change-namespace + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clang-apply-replacements + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clang-doc + - `7` + - `7` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clang-move + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clang-query + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clang-tidy + - `11` + - `11` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clangd + - `47` + - `47` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/clangd/xpc + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/include/common + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/include-fixer + - `2` + - `2` + - `0` + - :good:`100%` + * - llvm/utils/release/llvm_package_355249/llvm/tools/clang/tools/extra/unittests/include-fixer/find-all-symbols + - `1` + - `1` + - `0` + - :good:`100%` + * - llvm/utils/TableGen + - `75` + - `9` + - `66` + - :part:`12%` + * - llvm/utils/TableGen/GlobalISel + - `17` + - `8` + - `9` + - :part:`47%` + * - llvm/utils/unittest/googlemock/include/gmock + - `11` + - `0` + - `11` + - :none:`0%` + * - llvm/utils/unittest/googlemock/include/gmock/internal + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/utils/unittest/googlemock/include/gmock/internal/custom + - `3` + - `0` + - `3` + - :none:`0%` + * - llvm/utils/unittest/googletest/include/gtest + - `10` + - `0` + - `10` + - :none:`0%` + * - llvm/utils/unittest/googletest/include/gtest/internal + - `11` + - `0` + - `11` + - :none:`0%` + * - llvm/utils/unittest/googletest/include/gtest/internal/custom + - `4` + - `0` + - `4` + - :none:`0%` + * - llvm/utils/unittest/googletest/src + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/unittest/UnitTestMain + - `1` + - `0` + - `1` + - :none:`0%` + * - llvm/utils/yaml-bench + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/standalone/include/Standalone + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/examples/standalone/lib/Standalone + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/examples/standalone/standalone-opt + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/standalone/standalone-translate + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch1 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch1/include/toy + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch1/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/toy/Ch2 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch2/include/toy + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch2/mlir + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch2/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/toy/Ch3 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch3/include/toy + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch3/mlir + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch3/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/toy/Ch4 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch4/include/toy + - `7` + - `7` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch4/mlir + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch4/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/toy/Ch5 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch5/include/toy + - `7` + - `7` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch5/mlir + - `5` + - `4` + - `1` + - :part:`80%` + * - mlir/examples/toy/Ch5/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/toy/Ch6 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch6/include/toy + - `7` + - `7` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch6/mlir + - `6` + - `5` + - `1` + - :part:`83%` + * - mlir/examples/toy/Ch6/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/examples/toy/Ch7 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch7/include/toy + - `7` + - `7` + - `0` + - :good:`100%` + * - mlir/examples/toy/Ch7/mlir + - `6` + - `5` + - `1` + - :part:`83%` + * - mlir/examples/toy/Ch7/parser + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/include/mlir + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/include/mlir/Analysis + - `8` + - `7` + - `1` + - :part:`87%` + * - mlir/include/mlir/Conversion/AffineToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/AVX512ToLLVM + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/include/mlir/Conversion/GPUCommon + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/GPUToNVVM + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/include/mlir/Conversion/GPUToROCDL + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/GPUToSPIRV + - `2` + - `1` + - `1` + - :part:`50%` + * - mlir/include/mlir/Conversion/GPUToVulkan + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/include/mlir/Conversion/LinalgToLLVM + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/include/mlir/Conversion/LinalgToSPIRV + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/LinalgToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/SCFToGPU + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/SCFToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/ShapeToSCF + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/ShapeToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/SPIRVToLLVM + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/StandardToLLVM + - `2` + - `1` + - `1` + - :part:`50%` + * - mlir/include/mlir/Conversion/StandardToSPIRV + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/VectorToLLVM + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/VectorToROCDL + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Conversion/VectorToSCF + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Affine + - `2` + - `1` + - `1` + - :part:`50%` + * - mlir/include/mlir/Dialect/Affine/EDSC + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Affine/IR + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/AVX512 + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/GPU + - `5` + - `4` + - `1` + - :part:`80%` + * - mlir/include/mlir/Dialect/Linalg + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/include/mlir/Dialect/Linalg/Analysis + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Linalg/EDSC + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Linalg/IR + - `3` + - `2` + - `1` + - :part:`66%` + * - mlir/include/mlir/Dialect/Linalg/Transforms + - `2` + - `1` + - `1` + - :part:`50%` + * - mlir/include/mlir/Dialect/Linalg/Utils + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/LLVMIR + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/LLVMIR/Transforms + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/OpenMP + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Quant + - `6` + - `5` + - `1` + - :part:`83%` + * - mlir/include/mlir/Dialect/SCF + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/SCF/EDSC + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/SDBM + - `3` + - `2` + - `1` + - :part:`66%` + * - mlir/include/mlir/Dialect/Shape/IR + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Shape/Transforms + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/SPIRV + - `11` + - `10` + - `1` + - :part:`90%` + * - mlir/include/mlir/Dialect/StandardOps/EDSC + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/StandardOps/IR + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/StandardOps/Transforms + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Utils + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Vector + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/include/mlir/Dialect/Vector/EDSC + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/include/mlir/EDSC + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/ExecutionEngine + - `5` + - `2` + - `3` + - :part:`40%` + * - mlir/include/mlir/Interfaces + - `7` + - `6` + - `1` + - :part:`85%` + * - mlir/include/mlir/IR + - `42` + - `9` + - `33` + - :part:`21%` + * - mlir/include/mlir/Pass + - `6` + - `0` + - `6` + - :none:`0%` + * - mlir/include/mlir/Support + - `10` + - `4` + - `6` + - :part:`40%` + * - mlir/include/mlir/TableGen + - `18` + - `17` + - `1` + - :part:`94%` + * - mlir/include/mlir/Target + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/include/mlir/Target/LLVMIR + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/include/mlir/Transforms + - `12` + - `7` + - `5` + - :part:`58%` + * - mlir/include/mlir-c + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Analysis + - `8` + - `7` + - `1` + - :part:`87%` + * - mlir/lib/Conversion + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/AffineToStandard + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/lib/Conversion/AVX512ToLLVM + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/GPUCommon + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/GPUToNVVM + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/lib/Conversion/GPUToROCDL + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/GPUToSPIRV + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/GPUToVulkan + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/LinalgToLLVM + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/LinalgToSPIRV + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/LinalgToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/SCFToGPU + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/SCFToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/ShapeToSCF + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/ShapeToStandard + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/SPIRVToLLVM + - `2` + - `1` + - `1` + - :part:`50%` + * - mlir/lib/Conversion/StandardToLLVM + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/StandardToSPIRV + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/VectorToLLVM + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/VectorToROCDL + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Conversion/VectorToSCF + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Affine/EDSC + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Affine/IR + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Affine/Transforms + - `8` + - `8` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Affine/Utils + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/AVX512/IR + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/lib/Dialect/GPU/IR + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/lib/Dialect/GPU/Transforms + - `5` + - `4` + - `1` + - :part:`80%` + * - mlir/lib/Dialect/Linalg/Analysis + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/lib/Dialect/Linalg/EDSC + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Linalg/IR + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Linalg/Transforms + - `11` + - `10` + - `1` + - :part:`90%` + * - mlir/lib/Dialect/Linalg/Utils + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/LLVMIR/IR + - `4` + - `1` + - `3` + - :part:`25%` + * - mlir/lib/Dialect/LLVMIR/Transforms + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/OpenMP/IR + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Quant/IR + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Quant/Transforms + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Quant/Utils + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/SCF + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/SCF/EDSC + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/SCF/Transforms + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/SDBM + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Shape/IR + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Shape/Transforms + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/SPIRV + - `8` + - `6` + - `2` + - :part:`75%` + * - mlir/lib/Dialect/SPIRV/Serialization + - `4` + - `2` + - `2` + - :part:`50%` + * - mlir/lib/Dialect/SPIRV/Transforms + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/StandardOps/EDSC + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/StandardOps/IR + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/StandardOps/Transforms + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/lib/Dialect/Vector + - `3` + - `2` + - `1` + - :part:`66%` + * - mlir/lib/Dialect/Vector/EDSC + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/lib/EDSC + - `2` + - `1` + - `1` + - :part:`50%` + * - mlir/lib/ExecutionEngine + - `5` + - `5` + - `0` + - :good:`100%` + * - mlir/lib/Interfaces + - `7` + - `7` + - `0` + - :good:`100%` + * - mlir/lib/IR + - `32` + - `32` + - `0` + - :good:`100%` + * - mlir/lib/Parser + - `12` + - `12` + - `0` + - :good:`100%` + * - mlir/lib/Pass + - `7` + - `6` + - `1` + - :part:`85%` + * - mlir/lib/Support + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/lib/TableGen + - `16` + - `16` + - `0` + - :good:`100%` + * - mlir/lib/Target/LLVMIR + - `8` + - `8` + - `0` + - :good:`100%` + * - mlir/lib/Transforms + - `19` + - `16` + - `3` + - :part:`84%` + * - mlir/lib/Transforms/Utils + - `7` + - `6` + - `1` + - :part:`85%` + * - mlir/lib/Translation + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/tools/mlir-cpu-runner + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/tools/mlir-cuda-runner + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/tools/mlir-linalg-ods-gen + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/tools/mlir-opt + - `1` + - `0` + - `1` + - :none:`0%` + * - mlir/tools/mlir-rocm-runner + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/tools/mlir-shlib + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/tools/mlir-tblgen + - `16` + - `16` + - `0` + - :good:`100%` + * - mlir/tools/mlir-translate + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/tools/mlir-vulkan-runner + - `4` + - `4` + - `0` + - :good:`100%` + * - mlir/unittests/Dialect + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/unittests/Dialect/Quant + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/unittests/Dialect/SPIRV + - `2` + - `2` + - `0` + - :good:`100%` + * - mlir/unittests/IR + - `3` + - `3` + - `0` + - :good:`100%` + * - mlir/unittests/Pass + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/unittests/SDBM + - `1` + - `1` + - `0` + - :good:`100%` + * - mlir/unittests/TableGen + - `3` + - `3` + - `0` + - :good:`100%` + * - openmp/libomptarget/deviceRTLs + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/libomptarget/deviceRTLs/amdgcn/src + - `3` + - `3` + - `0` + - :good:`100%` + * - openmp/libomptarget/deviceRTLs/common + - `8` + - `4` + - `4` + - :part:`50%` + * - openmp/libomptarget/deviceRTLs/nvptx/src + - `2` + - `1` + - `1` + - :part:`50%` + * - openmp/libomptarget/include + - `2` + - `1` + - `1` + - :part:`50%` + * - openmp/libomptarget/plugins/cuda/src + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/libomptarget/plugins/generic-elf-64bit/src + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/libomptarget/plugins/ve/src + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/libomptarget/src + - `8` + - `0` + - `8` + - :none:`0%` + * - openmp/runtime/doc/doxygen + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/runtime/src + - `74` + - `37` + - `37` + - :part:`50%` + * - openmp/runtime/src/thirdparty/ittnotify + - `6` + - `0` + - `6` + - :none:`0%` + * - openmp/runtime/src/thirdparty/ittnotify/legacy + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/tools/archer + - `1` + - `0` + - `1` + - :none:`0%` + * - openmp/tools/archer/tests/ompt + - `1` + - `1` + - `0` + - :good:`100%` + * - openmp/tools/multiplex + - `1` + - `1` + - `0` + - :good:`100%` + * - openmp/tools/multiplex/tests + - `1` + - `1` + - `0` + - :good:`100%` + * - openmp/tools/multiplex/tests/custom_data_storage + - `2` + - `2` + - `0` + - :good:`100%` + * - openmp/tools/multiplex/tests/print + - `2` + - `2` + - `0` + - :good:`100%` + * - parallel-libs/acxxel + - `6` + - `4` + - `2` + - :part:`66%` + * - parallel-libs/acxxel/examples + - `1` + - `1` + - `0` + - :good:`100%` + * - parallel-libs/acxxel/tests + - `5` + - `4` + - `1` + - :part:`80%` + * - polly/include/polly + - `22` + - `22` + - `0` + - :good:`100%` + * - polly/include/polly/CodeGen + - `14` + - `14` + - `0` + - :good:`100%` + * - polly/include/polly/Support + - `11` + - `11` + - `0` + - :good:`100%` + * - polly/lib/Analysis + - `9` + - `9` + - `0` + - :good:`100%` + * - polly/lib/CodeGen + - `15` + - `15` + - `0` + - :good:`100%` + * - polly/lib/Exchange + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/lib/External/isl + - `67` + - `1` + - `66` + - :part:`1%` + * - polly/lib/External/isl/imath + - `3` + - `0` + - `3` + - :none:`0%` + * - polly/lib/External/isl/imath_wrap + - `4` + - `0` + - `4` + - :none:`0%` + * - polly/lib/External/isl/include/isl + - `62` + - `8` + - `54` + - :part:`12%` + * - polly/lib/External/isl/interface + - `5` + - `1` + - `4` + - :part:`20%` + * - polly/lib/External/pet/include + - `1` + - `0` + - `1` + - :none:`0%` + * - polly/lib/External/ppcg + - `17` + - `0` + - `17` + - :none:`0%` + * - polly/lib/Plugin + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/lib/Support + - `10` + - `10` + - `0` + - :good:`100%` + * - polly/lib/Transform + - `14` + - `14` + - `0` + - :good:`100%` + * - polly/tools/GPURuntime + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/unittests/DeLICM + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/unittests/Flatten + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/unittests/Isl + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/unittests/ScheduleOptimizer + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/unittests/ScopPassManager + - `1` + - `1` + - `0` + - :good:`100%` + * - polly/unittests/Support + - `1` + - `1` + - `0` + - :good:`100%` + * - pstl/include/pstl/internal + - `22` + - `18` + - `4` + - :part:`81%` + * - Total + - :total:`14021` + - :total:`6759` + - :total:`7262` + - :total:`48%` diff --git a/gnu/llvm/clang/docs/ClangPlugins.rst b/gnu/llvm/clang/docs/ClangPlugins.rst index 23e037e197c..4194491d396 100644 --- a/gnu/llvm/clang/docs/ClangPlugins.rst +++ b/gnu/llvm/clang/docs/ClangPlugins.rst @@ -63,6 +63,56 @@ registering it using ``PragmaHandlerRegistry::Add<>``: static PragmaHandlerRegistry::Add Y("example_pragma","example pragma description"); +Defining attributes +=================== + +Plugins can define attributes by declaring a ``ParsedAttrInfo`` and registering +it using ``ParsedAttrInfoRegister::Add<>``: + +.. code-block:: c++ + + class ExampleAttrInfo : public ParsedAttrInfo { + public: + ExampleAttrInfo() { + Spellings.push_back({ParsedAttr::AS_GNU,"example"}); + } + AttrHandling handleDeclAttribute(Sema &S, Decl *D, + const ParsedAttr &Attr) const override { + // Handle the attribute + return AttributeApplied; + } + }; + + static ParsedAttrInfoRegistry::Add Z("example_attr","example attribute description"); + +The members of ``ParsedAttrInfo`` that a plugin attribute must define are: + + * ``Spellings``, which must be populated with every `Spelling + `_ of the + attribute, each of which consists of an attribute syntax and how the + attribute name is spelled for that syntax. If the syntax allows a scope then + the spelling must be "scope::attr" if a scope is present or "::attr" if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + +The members of ``ParsedAttrInfo`` that may need to be defined, depending on the +attribute, are: + + * ``NumArgs`` and ``OptArgs``, which set the number of required and optional + arguments to the attribute. + * ``diagAppertainsToDecl``, which checks if the attribute has been used on the + right kind of declaration and issues a diagnostic if not. + * ``diagLangOpts``, which checks if the attribute is permitted for the current + language mode and issues a diagnostic if not. + * ``existsInTarget``, which checks if the attribute is permitted for the given + target. + +To see a working example of an attribute plugin, see `the Attribute.cpp example +`_. + Putting it all together ======================= diff --git a/gnu/llvm/clang/docs/CommandGuide/clang.rst b/gnu/llvm/clang/docs/CommandGuide/clang.rst index 8b9f4854691..2dfeafd1817 100644 --- a/gnu/llvm/clang/docs/CommandGuide/clang.rst +++ b/gnu/llvm/clang/docs/CommandGuide/clang.rst @@ -1,5 +1,5 @@ -clang, clang++, clang-cpp - the Clang C, C++, and Objective-C compiler -====================================================================== +clang - the Clang C, C++, and Objective-C compiler +================================================== SYNOPSIS -------- @@ -146,7 +146,7 @@ Language Selection and Mode Options ISO C 2017 with GNU extensions - The default C language standard is ``gnu11``, except on PS4, where it is + The default C language standard is ``gnu17``, except on PS4, where it is ``gnu99``. Supported values for the C++ language are: @@ -246,7 +246,9 @@ Language Selection and Mode Options .. option:: -ffreestanding Indicate that the file should be compiled for a freestanding, not a hosted, - environment. + environment. Note that it is assumed that a freestanding environment will + additionally provide `memcpy`, `memmove`, `memset` and `memcmp` + implementations, as these are needed for efficient codegen for many programs. .. option:: -fno-builtin @@ -383,7 +385,7 @@ Code Generation Options :option:`-Og` Like :option:`-O1`. In future versions, this option might disable different optimizations in order to improve debuggability. - :option:`-O` Equivalent to :option:`-O2`. + :option:`-O` Equivalent to :option:`-O1`. :option:`-O4` and higher @@ -472,6 +474,16 @@ Code Generation Options optimization. With "thin", :doc:`ThinLTO <../ThinLTO>` compilation is invoked instead. + .. note:: + + On Darwin, when using :option:`-flto` along with :option:`-g` and + compiling and linking in separate steps, you also need to pass + ``-Wl,-object_path_lto,.o`` at the linking step to instruct the + ld64 linker not to delete the temporary object file generated during Link + Time Optimization (this flag is automatically passed to the linker by Clang + if compilation and linking are done in a single step). This allows debugging + the executable as well as generating the ``.dSYM`` bundle using :manpage:`dsymutil(1)`. + Driver Options ~~~~~~~~~~~~~~ @@ -651,4 +663,4 @@ output of the compiler, along with information to reproduce. SEE ALSO -------- -:manpage:`as(1)`, :manpage:`clang-local(1)`, :manpage:`ld(1)` +:manpage:`as(1)`, :manpage:`ld(1)` diff --git a/gnu/llvm/clang/docs/ConstantInterpreter.rst b/gnu/llvm/clang/docs/ConstantInterpreter.rst index a86161c8fa0..eba637585b8 100644 --- a/gnu/llvm/clang/docs/ConstantInterpreter.rst +++ b/gnu/llvm/clang/docs/ConstantInterpreter.rst @@ -8,129 +8,256 @@ Constant Interpreter Introduction ============ -The constexpr interpreter aims to replace the existing tree evaluator in clang, improving performance on constructs which are executed inefficiently by the evaluator. The interpreter is activated using the following flags: +The constexpr interpreter aims to replace the existing tree evaluator in +clang, improving performance on constructs which are executed inefficiently +by the evaluator. The interpreter is activated using the following flags: -* ``-fexperimental-new-constant-interpreter`` enables the interpreter, emitting an error if an unsupported feature is encountered +* ``-fexperimental-new-constant-interpreter`` enables the interpreter, + emitting an error if an unsupported feature is encountered Bytecode Compilation ==================== -Bytecode compilation is handled in ``ByteCodeStmtGen.h`` for statements and ``ByteCodeExprGen.h`` for expressions. The compiler has two different backends: one to generate bytecode for functions (``ByteCodeEmitter``) and one to directly evaluate expressions as they are compiled, without generating bytecode (``EvalEmitter``). All functions are compiled to bytecode, while toplevel expressions used in constant contexts are directly evaluated since the bytecode would never be reused. This mechanism aims to pave the way towards replacing the evaluator, improving its performance on functions and loops, while being just as fast on single-use toplevel expressions. - -The interpreter relies on stack-based, strongly-typed opcodes. The glue logic between the code generator, along with the enumeration and description of opcodes, can be found in ``Opcodes.td``. The opcodes are implemented as generic template methods in ``Interp.h`` and instantiated with the relevant primitive types by the interpreter loop or by the evaluating emitter. +Bytecode compilation is handled in ``ByteCodeStmtGen.h`` for statements +and ``ByteCodeExprGen.h`` for expressions. The compiler has two different +backends: one to generate bytecode for functions (``ByteCodeEmitter``) and +one to directly evaluate expressions as they are compiled, without +generating bytecode (``EvalEmitter``). All functions are compiled to +bytecode, while toplevel expressions used in constant contexts are directly +evaluated since the bytecode would never be reused. This mechanism aims to +pave the way towards replacing the evaluator, improving its performance on +functions and loops, while being just as fast on single-use toplevel +expressions. + +The interpreter relies on stack-based, strongly-typed opcodes. The glue +logic between the code generator, along with the enumeration and +description of opcodes, can be found in ``Opcodes.td``. The opcodes are +implemented as generic template methods in ``Interp.h`` and instantiated +with the relevant primitive types by the interpreter loop or by the +evaluating emitter. Primitive Types --------------- * ``PT_{U|S}int{8|16|32|64}`` - Signed or unsigned integers of a specific bit width, implemented using the ```Integral``` type. + Signed or unsigned integers of a specific bit width, implemented using + the ```Integral``` type. * ``PT_{U|S}intFP`` - Signed or unsigned integers of an arbitrary, but fixed width used to implement - integral types which are required by the target, but are not supported by the host. - Under the hood, they rely on APValue. The ``Integral`` specialisation for these - types is required by opcodes to share an implementation with fixed integrals. + Signed or unsigned integers of an arbitrary, but fixed width used to + implement integral types which are required by the target, but are not + supported by the host. Under the hood, they rely on APValue. The + ``Integral`` specialisation for these types is required by opcodes to + share an implementation with fixed integrals. * ``PT_Bool`` - Representation for boolean types, essentially a 1-bit unsigned ``Integral``. + Representation for boolean types, essentially a 1-bit unsigned + ``Integral``. * ``PT_RealFP`` - Arbitrary, but fixed precision floating point numbers. Could be specialised in - the future similarly to integers in order to improve floating point performance. + Arbitrary, but fixed precision floating point numbers. Could be + specialised in the future similarly to integers in order to improve + floating point performance. * ``PT_Ptr`` - Pointer type, defined in ``"Pointer.h"``. + Pointer type, defined in ``"Pointer.h"``. A pointer can be either null, + reference interpreter-allocated memory (``BlockPointer``) or point to an + address which can be derived, but not accessed (``ExternPointer``). * ``PT_FnPtr`` - Function pointer type, can also be a null function pointer. Defined in ``"Pointer.h"``. + Function pointer type, can also be a null function pointer. Defined + in ``"FnPointer.h"``. * ``PT_MemPtr`` - Member pointer type, can also be a null member pointer. Defined in ``"Pointer.h"`` + Member pointer type, can also be a null member pointer. Defined + in ``"MemberPointer.h"`` + +* ``PT_VoidPtr`` + + Void pointer type, can be used for rount-trip casts. Represented as + the union of all pointers which can be cast to void. + Defined in ``"VoidPointer.h"``. + +* ``PT_ObjCBlockPtr`` + + Pointer type for ObjC blocks. Defined in ``"ObjCBlockPointer.h"``. Composite types --------------- -The interpreter distinguishes two kinds of composite types: arrays and records. Unions are represented as records, except a single field can be marked as active. The contents of inactive fields are kept until they -are reactivated and overwritten. +The interpreter distinguishes two kinds of composite types: arrays and +records (structs and classes). Unions are represented as records, except +at most a single field can be marked as active. The contents of inactive +fields are kept until they are reactivated and overwritten. +Complex numbers (``_Complex``) and vectors +(``__attribute((vector_size(16)))``) are treated as arrays. Bytecode Execution ================== -Bytecode is executed using a stack-based interpreter. The execution context consists of an ``InterpStack``, along with a chain of ``InterpFrame`` objects storing the call frames. Frames are built by call instructions and destroyed by return instructions. They perform one allocation to reserve space for all locals in a single block. These objects store all the required information to emit stack traces whenever evaluation fails. +Bytecode is executed using a stack-based interpreter. The execution +context consists of an ``InterpStack``, along with a chain of +``InterpFrame`` objects storing the call frames. Frames are built by +call instructions and destroyed by return instructions. They perform +one allocation to reserve space for all locals in a single block. +These objects store all the required information to emit stack traces +whenever evaluation fails. Memory Organisation =================== Memory management in the interpreter relies on 3 data structures: ``Block`` -object which store the data and associated inline metadata, ``Pointer`` objects -which refer to or into blocks, and ``Descriptor`` structures which describe -blocks and subobjects nested inside blocks. +objects which store the data and associated inline metadata, ``Pointer`` +objects which refer to or into blocks, and ``Descriptor`` structures which +describe blocks and subobjects nested inside blocks. Blocks ------ -Blocks contain data interleaved with metadata. They are allocated either statically -in the code generator (globals, static members, dummy parameter values etc.) or -dynamically in the interpreter, when creating the frame containing the local variables -of a function. Blocks are associated with a descriptor that characterises the entire -allocation, along with a few additional attributes: - -* ``IsStatic`` indicates whether the block has static duration in the interpreter, i.e. it is not a local in a frame. - -* ``IsExtern`` indicates that the block was created for an extern and the storage cannot be read or written. +Blocks contain data interleaved with metadata. They are allocated either +statically in the code generator (globals, static members, dummy parameter +values etc.) or dynamically in the interpreter, when creating the frame +containing the local variables of a function. Blocks are associated with a +descriptor that characterises the entire allocation, along with a few +additional attributes: + +* ``IsStatic`` indicates whether the block has static duration in the + interpreter, i.e. it is not a local in a frame. + +* ``DeclID`` identifies each global declaration (it is set to an invalid + and irrelevant value for locals) in order to prevent illegal writes and + reads involving globals and temporaries with static storage duration. + +Static blocks are never deallocated, but local ones might be deallocated +even when there are live pointers to them. Pointers are only valid as +long as the blocks they point to are valid, so a block with pointers to +it whose lifetime ends is kept alive until all pointers to it go out of +scope. Since the frame is destroyed on function exit, such blocks are +turned into a ``DeadBlock`` and copied to storage managed by the +interpreter itself, not the frame. Reads and writes to these blocks are +illegal and cause an appropriate diagnostic to be emitted. When the last +pointer goes out of scope, dead blocks are also deallocated. + +The lifetime of blocks is managed through 3 methods stored in the +descriptor of the block: + +* **CtorFn**: initializes the metadata which is store in the block, + alongside actual data. Invokes the default constructors of objects + which are not trivial (``Pointer``, ``RealFP``, etc.) -* ``DeclID`` identifies each global declaration (it is set to an invalid and irrelevant value for locals) in order to prevent illegal writes and reads involving globals and temporaries with static storage duration. - -Static blocks are never deallocated, but local ones might be deallocated even when there are live pointers to them. Pointers are only valid as long as the blocks they point to are valid, so a block with pointers to it whose lifetime ends is kept alive until all pointers to it go out of scope. Since the frame is destroyed on function exit, such blocks are turned into a ``DeadBlock`` and copied to storage managed by the interpreter itself, not the frame. Reads and writes to these blocks are illegal and cause an appropriate diagnostic to be emitted. When the last pointer goes out of scope, dead blocks are also deallocated. - -The lifetime of blocks is managed through 3 methods stored in the descriptor of the block: - -* **CtorFn**: initializes the metadata which is store in the block, alongside actual data. Invokes the default constructors of objects which are not trivial (``Pointer``, ``RealFP``, etc.) * **DtorFn**: invokes the destructors of non-trivial objects. -* **MoveFn**: moves a block to dead storage. -Non-static blocks track all the pointers into them through an intrusive doubly-linked list, this is required in order to adjust all pointers when transforming a block into a dead block. +* **MoveFn**: moves a block to dead storage. -Descriptors ------------ +Non-static blocks track all the pointers into them through an intrusive +doubly-linked list, required to adjust and invalidate all pointers when +transforming a block into a dead block. If the lifetime of an object ends, +all pointers to it are invalidated, emitting the appropriate diagnostics when +dereferenced. -Descriptor are generated at bytecode compilation time and contain information required to determine if a particular memory access is allowed in constexpr. Even though there is a single descriptor object, it encodes information for several kinds of objects: +The interpreter distinguishes 3 different kinds of blocks: * **Primitives** - A block containing a primitive reserved storage only for the primitive. + A block containing a single primitive with no additional metadata. * **Arrays of primitives** - An array of primitives contains a pointer to an ``InitMap`` storage as its first field: the initialisation map is a bit map indicating all elements of the array which were initialised. If the pointer is null, no elements were initialised, while a value of ``(InitMap)-1`` indicates that the object was fully initialised. when all fields are initialised, the map is deallocated and replaced with that token. + An array of primitives contains a pointer to an ``InitMap`` storage as its + first field: the initialisation map is a bit map indicating all elements of + the array which were initialised. If the pointer is null, no elements were + initialised, while a value of ``(InitMap*)-1`` indicates that the object was + fully initialised. When all fields are initialised, the map is deallocated + and replaced with that token. - Array elements are stored sequentially, without padding, after the pointer to the map. + Array elements are stored sequentially, without padding, after the pointer + to the map. * **Arrays of composites and records** - Each element in an array of composites is preceded by an ``InlineDescriptor``. Descriptors and elements are stored sequentially in the block. Records are laid out identically to arrays of composites: each field and base class is preceded by an inline descriptor. The ``InlineDescriptor`` has the following field: + Each element in an array of composites is preceded by an ``InlineDescriptor`` + which stores the attributes specific to the field and not the whole + allocation site. Descriptors and elements are stored sequentially in the + block. + Records are laid out identically to arrays of composites: each field and base + class is preceded by an inline descriptor. The ``InlineDescriptor`` + has the following fields: + + * **Offset**: byte offset into the array or record, used to step back to the + parent array or record. + * **IsConst**: flag indicating if the field is const-qualified. + * **IsInitialized**: flag indicating whether the field or element was + initialized. For non-primitive fields, this is only relevant to determine + the dynamic type of objects during construction. + * **IsBase**: flag indicating whether the record is a base class. In that + case, the offset can be used to identify the derived class. + * **IsActive**: indicates if the field is the active field of a union. + * **IsMutable**: indicates if the field is marked as mutable. + +Inline descriptors are filled in by the `CtorFn` of blocks, which leaves storage +in an uninitialised, but valid state. - * **Offset**: byte offset into the array or record, used to step back to the parent array or record. - * **IsConst**: flag indicating if the field is const-qualified. - * **IsInitialized**: flag indicating whether the field or element was initialized. For non-primitive fields, this is only relevant for base classes. - * **IsBase**: flag indicating whether the record is a base class. In that case, the offset can be used to identify the derived class. - * **IsActive**: indicates if the field is the active field of a union. - * **IsMutable**: indicates if the field is marked as mutable. +Descriptors +----------- -Inline descriptors are filled in by the `CtorFn` of blocks, which leaves storage in an uninitialised, but valid state. +Descriptors are generated at bytecode compilation time and contain information +required to determine if a particular memory access is allowed in constexpr. +They also carry all the information required to emit a diagnostic involving +a memory access, such as the declaration which originates the block. +Currently there is a single kind of descriptor encoding information for all +block types. Pointers -------- -Pointers track a ``Pointee``, the block to which they point or ``nullptr`` for null pointers, along with a ``Base`` and an ``Offset``. The base identifies the innermost field, while the offset points to an array element relative to the base (including one-past-end pointers). Most subobject the pointer points to in block, while the offset identifies the array element the pointer points to. These two fields allow all pointers to be uniquely identified and disambiguated. +Pointers, implemented in ``Pointer.h`` are represented as a tagged union. +Some of these may not yet be available in upstream ``clang``. + + * **BlockPointer**: used to reference memory allocated and managed by the + interpreter, being the only pointer kind which allows dereferencing in the + interpreter + * **ExternPointer**: points to memory which can be addressed, but not read by + the interpreter. It is equivalent to APValue, tracking a declaration and a path + of fields and indices into that allocation. + * **TargetPointer**: represents a target address derived from a base address + through pointer arithmetic, such as ``((int *)0x100)[20]``. Null pointers are + target pointers with a zero offset. + * **TypeInfoPointer**: tracks information for the opaque type returned by + ``typeid`` + * **InvalidPointer**: is dummy pointer created by an invalid operation which + allows the interpreter to continue execution. Does not allow pointer + arithmetic or dereferencing. + +Besides the previously mentioned union, a number of other pointer-like types +have their own type: + + * **ObjCBlockPointer** tracks Objective-C blocks + * **FnPointer** tracks functions and lazily caches their compiled version + * **MemberPointer** tracks C++ object members + +Void pointers, which can be built by casting any of the aforementioned +pointers, are implemented as a union of all pointer types. The ``BitCast`` +opcode is responsible for performing all legal conversions between these +types and primitive integers. + +BlockPointer +~~~~~~~~~~~~ + +Block pointers track a ``Pointee``, the block to which they point, along +with a ``Base`` and an ``Offset``. The base identifies the innermost field, +while the offset points to an array element relative to the base (including +one-past-end pointers). The offset identifies the array element or field +which is referenced, while the base points to the outer object or array which +contains the field. These two fields allow all pointers to be uniquely +identified, disambiguated and characterised. As an example, consider the following structure: @@ -149,9 +276,14 @@ As an example, consider the following structure: }; constexpr A a; -On the target, ``&a`` and ``&a.b.x`` are equal. So are ``&a.c[0]`` and ``&a.c[0].a``. In the interpreter, all these pointers must be distinguished since the are all allowed to address distinct range of memory. +On the target, ``&a`` and ``&a.b.x`` are equal. So are ``&a.c[0]`` and +``&a.c[0].a``. In the interpreter, all these pointers must be +distinguished since the are all allowed to address distinct range of +memory. -In the interpreter, the object would require 240 bytes of storage and would have its field interleaved with metadata. The pointers which can be derived to the object are illustrated in the following diagram: +In the interpreter, the object would require 240 bytes of storage and +would have its field interleaved with metadata. The pointers which can +be derived to the object are illustrated in the following diagram: :: @@ -164,9 +296,63 @@ In the interpreter, the object would require 240 bytes of storage and would have a |&a.b.x &a.y &a.c |&a.c[0].a |&a.c[1].a | &a.b &a.c[0] &a.c[1] &a.z -The ``Base`` offset of all pointers points to the start of a field or an array and is preceded by an inline descriptor (unless ``Base == 0``, pointing to the root). All the relevant attributes can be read from either the inline descriptor or the descriptor of the block. +The ``Base`` offset of all pointers points to the start of a field or +an array and is preceded by an inline descriptor (unless ``Base`` is +zero, pointing to the root). All the relevant attributes can be read +from either the inline descriptor or the descriptor of the block. + + +Array elements are identified by the ``Offset`` field of pointers, +pointing to past the inline descriptors for composites and before +the actual data in the case of primitive arrays. The ``Offset`` +points to the offset where primitives can be read from. As an example, +``a.c + 1`` would have the same base as ``a.c`` since it is an element +of ``a.c``, but its offset would point to ``&a.c[1]``. The +array-to-pointer decay operation adjusts a pointer to an array (where +the offset is equal to the base) to a pointer to the first element. + +ExternPointer +~~~~~~~~~~~~~ + +Extern pointers can be derived, pointing into symbols which are not +readable from constexpr. An external pointer consists of a base +declaration, along with a path designating a subobject, similar to +the ``LValuePath`` of an APValue. Extern pointers can be converted +to block pointers if the underlying variable is defined after the +pointer is created, as is the case in the following example: + +.. code-block:: c + + extern const int a; + constexpr const int *p = &a; + const int a = 5; + static_assert(*p == 5, "x"); + +TargetPointer +~~~~~~~~~~~~~ + +While null pointer arithmetic or integer-to-pointer conversion is +banned in constexpr, some expressions on target offsets must be folded, +replicating the behaviour of the ``offsetof`` builtin. Target pointers +are characterised by 3 offsets: a field offset, an array offset and a +base offset, along with a descriptor specifying the type the pointer is +supposed to refer to. Array indexing adjusts the array offset, while the +field offset is adjusted when a pointer to a member is created. Casting +an integer to a pointer sets the value of the base offset. As a special +case, null pointers are target pointers with all offsets set to 0. + +TypeInfoPointer +~~~~~~~~~~~~~~~ + +``TypeInfoPointer`` tracks two types: the type assigned to +``std::type_info`` and the type which was passed to ``typeinfo``. + +InvalidPointer +~~~~~~~~~~~~~~ -Array elements are identified by the ``Offset`` field of pointers, pointing to past the inline descriptors for composites and before the actual data in the case of primitive arrays. The ``Offset`` points to the offset where primitives can be read from. As an example, ``a.c + 1`` would have the same base as ``a.c`` since it is an element of ``a.c``, but its offset would point to ``&a.c[1]``. The ``*`` operation narrows the scope of the pointer, adjusting the base to ``&a.c[1]``. The reverse operator, ``&``, expands the scope of ``&a.c[1]``, turning it into ``a.c + 1``. When a one-past-end pointer is narrowed, its offset is set to ``-1`` to indicate that it is an invalid value (expanding returns the past-the-end pointer). As a special case, narrowing ``&a.c`` results in ``&a.c[0]``. The `narrow` and `expand` methods can be used to follow the chain of equivalent pointers. +Such pointers are built by operations which cannot generate valid +pointers, allowing the interpreter to continue execution after emitting +a warning. Inspecting such a pointer stops execution. TODO ==== @@ -174,20 +360,24 @@ TODO Missing Language Features ------------------------- -* Definition of externs must override previous declaration * Changing the active field of unions -* Union copy constructors -* ``typeid`` * ``volatile`` * ``__builtin_constant_p`` -* ``std::initializer_list`` -* lambdas -* range-based for loops -* ``vector_size`` * ``dynamic_cast`` +* ``new`` and ``delete`` +* Fixed Point numbers and arithmetic on Complex numbers +* Several builtin methods, including string operations and + ``__builtin_bit_cast`` +* Continue-after-failure: a form of exception handling at the bytecode + level should be implemented to allow execution to resume. As an example, + argument evaluation should resume after the computation of an argument fails. +* Pointer-to-Integer conversions +* Lazy descriptors: the interpreter creates a ``Record`` and ``Descriptor`` + when it encounters a type: ones which are not yet defined should be lazily + created when required Known Bugs ---------- -* Pointer comparison for equality needs to narrow/expand pointers -* If execution fails, memory storing APInts and APFloats is leaked when the stack is cleared +* If execution fails, memory storing APInts and APFloats is leaked when the + stack is cleared diff --git a/gnu/llvm/clang/docs/DataFlowSanitizer.rst b/gnu/llvm/clang/docs/DataFlowSanitizer.rst index e0e9d74efde..44956037490 100644 --- a/gnu/llvm/clang/docs/DataFlowSanitizer.rst +++ b/gnu/llvm/clang/docs/DataFlowSanitizer.rst @@ -20,6 +20,32 @@ specific class of bugs on its own. Instead, it provides a generic dynamic data flow analysis framework to be used by clients to help detect application-specific issues within their own code. +How to build libc++ with DFSan +============================== + +DFSan requires either all of your code to be instrumented or for uninstrumented +functions to be listed as ``uninstrumented`` in the `ABI list`_. + +If you'd like to have instrumented libc++ functions, then you need to build it +with DFSan instrumentation from source. Here is an example of how to build +libc++ and the libc++ ABI with data flow sanitizer instrumentation. + +.. code-block:: console + + cd libcxx-build + + # An example using ninja + cmake -GNinja path/to/llvm-project/llvm \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DLLVM_USE_SANITIZER="DataFlow" \ + -DLLVM_ENABLE_LIBCXX=ON \ + -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" + + ninja cxx cxxabi + +Note: Ensure you are building with a sufficiently new version of Clang. + Usage ===== @@ -33,6 +59,8 @@ The APIs are defined in the header file ``sanitizer/dfsan_interface.h``. For further information about each function, please refer to the header file. +.. _ABI list: + ABI List -------- diff --git a/gnu/llvm/clang/docs/DiagnosticsReference.rst b/gnu/llvm/clang/docs/DiagnosticsReference.rst index afd38929fb6..2fab8b5f302 100644 --- a/gnu/llvm/clang/docs/DiagnosticsReference.rst +++ b/gnu/llvm/clang/docs/DiagnosticsReference.rst @@ -314,9 +314,13 @@ This diagnostic is enabled by default. **Diagnostic text:** -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 considers use of overloaded operator '`:placeholder:`A`:diagtext:`' (with operand types` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C`:diagtext:`) to be ambiguous despite there being a unique best viable function`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 considers use of overloaded operator '`:placeholder:`A`:diagtext:`' (with operand types` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C`:diagtext:`) to be ambiguous despite there being a unique best viable function`|+-----------------------------------------------+| +| || |nbsp| :diagtext:`with non-reversed arguments`|| +| |+-----------------------------------------------+| +| || || +| |+-----------------------------------------------+| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ -Wanalyzer-incompatible-plugin @@ -555,24 +559,7 @@ This diagnostic is enabled by default. -Wasm ----- -This diagnostic is enabled by default. - -Controls `-Wasm-ignored-qualifier`_, `-Wasm-operand-widths`_. - - --Wasm-ignored-qualifier ------------------------ -This diagnostic is enabled by default. - -**Diagnostic text:** - -+----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignored` |nbsp| :placeholder:`A` |nbsp| :diagtext:`qualifier on asm`| -+----------------------------------------------------------------------------------------------------------+ - -+-------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`meaningless 'volatile' on asm outside function`| -+-------------------------------------------------------------------------------------+ +Synonym for `-Wasm-operand-widths`_. -Wasm-operand-widths @@ -1045,9 +1032,13 @@ This diagnostic is enabled by default. **Diagnostic text:** -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`braces around scalar initializer`| -+-----------------------------------------------------------------------+ ++------------------------------------------------------------+----------------------------+-----------------------+ +|:warning:`warning:` |nbsp| :diagtext:`braces around` |nbsp| |+--------------------------+|:diagtext:`initializer`| +| ||:diagtext:`scalar` |nbsp| || | +| |+--------------------------+| | +| || || | +| |+--------------------------+| | ++------------------------------------------------------------+----------------------------+-----------------------+ -Wbridge-cast @@ -1642,6 +1633,10 @@ Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`aggregate initialization of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with user-declared constructors is incompatible with C++20`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'consteval' specifier is incompatible with C++ standards before C++20`| +------------------------------------------------------------------------------------------------------------+ @@ -1650,10 +1645,6 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`'constinit' specifier is incompatible with C++ standards before C++20`| +------------------------------------------------------------------------------------------------------------+ -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`aggregate initialization of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with user-declared constructors is incompatible with C++20`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - +------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`this expression will be parsed as explicit(bool) in C++20`| +------------------------------------------------------------------------------------------------+ @@ -2164,6 +2155,10 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_ |:warning:`warning:` |nbsp| :diagtext:`scalar initialized from empty initializer list is incompatible with C++98`| +----------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`initializing` |nbsp| :placeholder:`A` |nbsp| :diagtext:`from an empty initializer list is incompatible with C++98`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are incompatible with C++98`| +-----------------------------------------------------------------------------------------------------------------+ @@ -2519,6 +2514,17 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14 +----------------------------------------------------------------------------------------+ +-Wc2x-extensions +---------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`omitting the parameter name in a function definition is a C2x extension`| ++--------------------------------------------------------------------------------------------------------------+ + + -Wc99-compat ------------ Some of the diagnostics controlled by this flag are enabled by default. @@ -2779,6 +2785,23 @@ Also controls `-Wnon-pod-varargs`_. +---------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------------------------------+ +-Wcmse-union-leak +----------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------+-------------------------------------------------+----------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`passing union across security boundary via` |nbsp| |+-----------------------------------------------+| |nbsp| :diagtext:`may leak information`| +| ||+---------------------------------------------+|| | +| |||:diagtext:`parameter` |nbsp| :placeholder:`B`||| | +| ||+---------------------------------------------+|| | +| |+-----------------------------------------------+| | +| ||:diagtext:`return value` || | +| |+-----------------------------------------------+| | ++-----------------------------------------------------------------------------------------+-------------------------------------------------+----------------------------------------+ + + -Wcomma ------- **Diagnostic text:** @@ -2940,9 +2963,9 @@ This diagnostic is enabled by default. ---------- **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`consumed analysis attribute is attached to member of class '`:placeholder:`A`:diagtext:`' which isn't marked as consumable`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`consumed analysis attribute is attached to member of class` |nbsp| :placeholder:`A` |nbsp| :diagtext:`which isn't marked as consumable`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`state of variable '`:placeholder:`A`:diagtext:`' must match at the entry and exit of loop`| @@ -4093,6 +4116,40 @@ Also controls `-Wdocumentation-unknown-command`_. +--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wdtor-name +----------- +Some of the diagnostics controlled by this flag are enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ considers this destructor name lookup to be ambiguous`| ++----------------------------------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'`| ++-----------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`qualified destructor name only found in lexical scope; omit the qualifier to find this type name by unqualified lookup`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +-Wdtor-typedef +-------------- +This diagnostic is an error by default, but the flag ``-Wno-dtor-typedef`` can be used to disable the error. + +**Diagnostic text:** + ++--------------------------------------------------------------------------------+------------------------+-------------------------------------------------------------+ +|:error:`error:` |nbsp| :diagtext:`destructor cannot be declared using a` |nbsp| |+----------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`of the class name`| +| ||:diagtext:`typedef` || | +| |+----------------------+| | +| ||:diagtext:`type alias`|| | +| |+----------------------+| | ++--------------------------------------------------------------------------------+------------------------+-------------------------------------------------------------+ + + -Wduplicate-decl-specifier -------------------------- Some of the diagnostics controlled by this flag are enabled by default. @@ -4432,6 +4489,39 @@ This diagnostic is enabled by default. +-----------------------------------------------------------------------------------------------------------------------------+ +-Wexcess-initializers +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-----------------------------------------------------------------+--------------------+-------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`excess elements in` |nbsp| |+------------------+| |nbsp| :diagtext:`initializer`| +| ||:diagtext:`array` || | +| |+------------------+| | +| ||:diagtext:`vector`|| | +| |+------------------+| | +| ||:diagtext:`scalar`|| | +| |+------------------+| | +| ||:diagtext:`union` || | +| |+------------------+| | +| ||:diagtext:`struct`|| | +| |+------------------+| | ++-----------------------------------------------------------------+--------------------+-------------------------------+ + ++---------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`excess elements in initializer for indivisible sizeless type` |nbsp| :placeholder:`A`| ++---------------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`excess elements in char array initializer`| ++--------------------------------------------------------------------------------+ + ++------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`initializer-string for char array is too long`| ++------------------------------------------------------------------------------------+ + + -Wexit-time-destructors ----------------------- **Diagnostic text:** @@ -4456,21 +4546,6 @@ Some of the diagnostics controlled by this flag are enabled by default. +-------------------------------------------------------------------------------------------------+ --Wexperimental-isel -------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-fexperimental-isel support for the '`:placeholder:`A`:diagtext:`' architecture is incomplete`| -+------------------------------------------------------------------------------------------------------------------------------------+ - -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`-fexperimental-isel support is incomplete for this architecture at the current optimization level`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - - -Wexplicit-initialize-call -------------------------- This diagnostic is enabled by default. @@ -5024,6 +5099,10 @@ This diagnostic is enabled by default. **Diagnostic text:** ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always overflow; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but format string expands to at least` |nbsp| :placeholder:`C`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always overflow; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but size argument is` |nbsp| :placeholder:`C`| +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -5042,6 +5121,15 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------+ +-Wframe-address +--------------- +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`calling '`:placeholder:`A`:diagtext:`' with a nonzero argument is unsafe`| ++---------------------------------------------------------------------------------------------------------------+ + + -Wframe-larger-than= -------------------- This diagnostic is enabled by default. @@ -5156,6 +5244,21 @@ Some of the diagnostics controlled by this flag are enabled by default. +-------------------------------------------------------------------------------+ +-Wglobal-isel +------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`-fglobal-isel support for the '`:placeholder:`A`:diagtext:`' architecture is incomplete`| ++------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`-fglobal-isel support is incomplete for this architecture at the current optimization level`| ++----------------------------------------------------------------------------------------------------------------------------------+ + + -Wgnu ----- Some of the diagnostics controlled by this flag are enabled by default. @@ -5552,6 +5655,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`after definition is ignored`| +-----------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'cmse\_nonsecure\_entry' cannot be applied to functions with internal linkage`| ++--------------------------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'dllexport' attribute ignored on explicit instantiation definition`| +---------------------------------------------------------------------------------------------------------+ @@ -6218,6 +6325,17 @@ Controls `-Wimplicit-function-declaration`_, `-Wimplicit-int`_. +----------------------------------------------------------------------------+ +-Wimplicit-const-int-float-conversion +------------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wimplicit-conversion-floating-point-to-bool -------------------------------------------- This diagnostic is enabled by default. @@ -6349,16 +6467,14 @@ Also controls `-Wobjc-signed-char-bool-implicit-int-conversion`_. ------------------------------- Some of the diagnostics controlled by this flag are enabled by default. +Also controls `-Wimplicit-const-int-float-conversion`_. + **Diagnostic text:** +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`may lose precision`| +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Wimplicit-retain-self ---------------------- @@ -6924,13 +7040,13 @@ This diagnostic is an error by default, but the flag ``-Wno-invalid-constexpr`` **Diagnostic text:** -+----------------------------------------------------+-------------------------+--------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`never produces a constant expression`| -| ||:diagtext:`function` || | -| |+-----------------------+| | -| ||:diagtext:`constructor`|| | -| |+-----------------------+| | -+----------------------------------------------------+-------------------------+--------------------------------------------------------+ ++-----------------------+-----------------------+--------+-------------------------+--------------------------------------------------------+ +|:error:`error:` |nbsp| |+---------------------+| |nbsp| |+-----------------------+| |nbsp| :diagtext:`never produces a constant expression`| +| ||:diagtext:`constexpr`|| ||:diagtext:`function` || | +| |+---------------------+| |+-----------------------+| | +| ||:diagtext:`consteval`|| ||:diagtext:`constructor`|| | +| |+---------------------+| |+-----------------------+| | ++-----------------------+-----------------------+--------+-------------------------+--------------------------------------------------------+ -Winvalid-iboutlet @@ -7325,10 +7441,54 @@ This diagnostic is enabled by default. **Diagnostic text:** -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`too many braces around scalar initializer`| -+--------------------------------------------------------------------------------+ ++---------------------------------------------------------------------+----------------------------+-----------------------+ +|:warning:`warning:` |nbsp| :diagtext:`too many braces around` |nbsp| |+--------------------------+|:diagtext:`initializer`| +| ||:diagtext:`scalar` |nbsp| || | +| |+--------------------------+| | +| || || | +| |+--------------------------+| | ++---------------------------------------------------------------------+----------------------------+-----------------------+ + + +-Wmax-tokens +------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the number of preprocessor source tokens (`:placeholder:`A`:diagtext:`) exceeds this token limit (`:placeholder:`B`:diagtext:`)`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the total number of preprocessor source tokens (`:placeholder:`A`:diagtext:`) exceeds the token limit (`:placeholder:`B`:diagtext:`)`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +The warning is issued if the number of pre-processor tokens exceeds +the token limit, which can be set in three ways: + +1. As a limit at a specific point in a file, using the ``clang max_tokens_here`` + pragma: + + .. code-block: c++ + #pragma clang max_tokens_here 1234 + +2. As a per-translation unit limit, using the ``-fmax-tokens=`` command-line + flag: + + .. code-block: console + clang -c a.cpp -fmax-tokens=1234 + +3. As a per-translation unit limit using the ``clang max_tokens_total`` pragma, + which works like and overrides the ``-fmax-tokens=`` flag: + + .. code-block: c++ + #pragma clang max_tokens_total 1234 + +These limits can be helpful in limiting code growth through included files. +Setting a token limit of zero means no limit. -Wmax-unsigned-zero ------------------- @@ -8174,7 +8334,7 @@ This diagnostic is an error by default, but the flag ``-Wno-modules-import-neste ------ Some of the diagnostics controlled by this flag are enabled by default. -Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wint-in-bool-context`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-flexible-array`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wrange-loop-construct`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtautological-compare`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wuser-defined-warnings`_, `-Wvolatile-register-var`_. +Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wframe-address`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wint-in-bool-context`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-flexible-array`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wrange-loop-construct`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtautological-compare`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wuser-defined-warnings`_, `-Wvolatile-register-var`_. -Wmove @@ -8294,6 +8454,21 @@ This diagnostic is enabled by default. Synonym for `-Wc++17-compat-mangling`_. +-Wnon-c-typedef-for-linkage +--------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------------+---------------------+----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`anonymous non-C-compatible type given name for linkage purposes by` |nbsp| |+-------------------+| |nbsp| :diagtext:`declaration; add a tag name here`| +| ||:diagtext:`typedef`|| | +| |+-------------------+| | +| ||:diagtext:`alias` || | +| |+-------------------+| | ++-----------------------------------------------------------------------------------------------------------------+---------------------+----------------------------------------------------+ + + -Wnon-gcc --------- Some of the diagnostics controlled by this flag are enabled by default. @@ -8371,6 +8546,17 @@ This diagnostic is an error by default, but the flag ``-Wno-non-pod-varargs`` ca +--------------------------------------------------------------------------------------------------------------------------+ +-Wnon-power-of-two-alignment +---------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`requested alignment is not a power of 2`| ++------------------------------------------------------------------------------+ + + -Wnon-virtual-dtor ------------------ **Diagnostic text:** @@ -9319,9 +9505,57 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`allocator with the 'thread' trait access has unspecified behavior on '`:placeholder:`A`:diagtext:`' directive`| +----------------------------------------------------------------------------------------------------------------------------------------------------+ -+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown context selector in '`:placeholder:`A`:diagtext:`' context selector set of 'omp declare variant' directive, ignored`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the context property '`:placeholder:`A`:diagtext:`' is not valid for the context selector '`:placeholder:`B`:diagtext:`' and the context set '`:placeholder:`C`:diagtext:`'; property ignored`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the context selector '`:placeholder:`A`:diagtext:`' in the context set '`:placeholder:`B`:diagtext:`' cannot have a score ('`:placeholder:`C`:diagtext:`'); score ignored`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the context selector '`:placeholder:`A`:diagtext:`' is not valid for the context set '`:placeholder:`B`:diagtext:`'; selector ignored`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the context selector '`:placeholder:`A`:diagtext:`' in context set '`:placeholder:`B`:diagtext:`' requires a context property defined in parentheses; selector ignored`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the context` |nbsp| |+--------------------+| |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' was used already in the same 'omp declare variant' directive;` |nbsp| |+--------------------+| |nbsp| :diagtext:`ignored`| +| ||:diagtext:`set` || ||:diagtext:`set` || | +| |+--------------------+| |+--------------------+| | +| ||:diagtext:`selector`|| ||:diagtext:`selector`|| | +| |+--------------------+| |+--------------------+| | +| ||:diagtext:`property`|| ||:diagtext:`property`|| | +| |+--------------------+| |+--------------------+| | ++----------------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid context property for the context selector '`:placeholder:`B`:diagtext:`' and the context set '`:placeholder:`C`:diagtext:`'; property ignored`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid context selector for the context set '`:placeholder:`B`:diagtext:`'; selector ignored`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is not a valid context set in a \`declare variant\`; set ignored`| ++--------------------------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`expected '`:placeholder:`A`:diagtext:`' after the` |nbsp| :placeholder:`B`:diagtext:`; '`:placeholder:`A`:diagtext:`' assumed`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------------------+----------------------+---------------------+----------------------+---------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`expected identifier or string literal describing a context` |nbsp| |+--------------------+|:diagtext:`;` |nbsp| |+--------------------+| |nbsp| :diagtext:`skipped`| +| ||:diagtext:`set` || ||:diagtext:`set` || | +| |+--------------------+| |+--------------------+| | +| ||:diagtext:`selector`|| ||:diagtext:`selector`|| | +| |+--------------------+| |+--------------------+| | +| ||:diagtext:`property`|| ||:diagtext:`property`|| | +| |+--------------------+| |+--------------------+| | ++---------------------------------------------------------------------------------------------------------+----------------------+---------------------+----------------------+---------------------------+ +---------------------------------------------------------------------------------+---------------------------------------------------+-------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`zero linear step (`:placeholder:`A` |nbsp| |+-------------------------------------------------+|:diagtext:`should probably be const)`| @@ -9431,6 +9665,10 @@ This diagnostic is enabled by default. | |+-----------------------------+| | +-----------------------------------------------------------------------------------------------------------------------+-------------------------------+----------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64`| ++-----------------------------------------------------------------------------------------------------------+ + +----------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`auto-vectorization requires HVX, use -mhvx to enable it`| +----------------------------------------------------------------------------------------------+ @@ -9763,6 +10001,14 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter | |+------------------+| | +--------------------------------------------------------+--------------------+------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'`| ++-----------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ considers this destructor name lookup to be ambiguous`| ++----------------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| | ||:diagtext:`copying variable` || | @@ -10297,9 +10543,44 @@ This diagnostic is enabled by default. +---------------------------+----------------------------------------------------------------+----------------------------------------------------------------------------------+ +-Wpointer-to-enum-cast +---------------------- +This diagnostic is enabled by default. + +Also controls `-Wvoid-pointer-to-enum-cast`_. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wpointer-to-int-cast --------------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. +This diagnostic is enabled by default. + +Also controls `-Wpointer-to-enum-cast`_, `-Wvoid-pointer-to-int-cast`_. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + + +-Wpointer-to-int-cast +--------------------- +This diagnostic is enabled by default. + +Also controls `-Wpointer-to-enum-cast`_, `-Wvoid-pointer-to-int-cast`_. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + -Wpointer-type-mismatch ----------------------- @@ -10608,22 +10889,22 @@ Controls `-Wrange-loop-bind-reference`_, `-Wrange-loop-construct`_. --------------------------- **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is always a copy because the range of type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`does not return a reference`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`binds to a temporary value produced by a range of type` |nbsp| :placeholder:`B`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Wrange-loop-construct ---------------------- **Diagnostic text:** -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| |nbsp| :diagtext:`is initialized with a value of a different type` |nbsp| :diagtext:`resulting in a copy`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`binds to a temporary constructed from a different type`| ++------------------------------------------------------------------------------------------------------------------------------------------------------+ -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`creates a copy from type` |nbsp| :placeholder:`C`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`loop variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`creates a copy from type` |nbsp| :placeholder:`B`| ++------------------------------------------------------------------------------------------------------------------------------------------------+ -Wreadonly-iboutlet-property @@ -10948,6 +11229,17 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wrewrite-not-bool +------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++20 requires return type of selected 'operator==' function for rewritten '`:placeholder:`B`:diagtext:`' comparison to be 'bool', not` |nbsp| :placeholder:`A`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Rsanitize-address ------------------ **Diagnostic text:** @@ -11481,6 +11773,10 @@ Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** ++-----------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`nesting \`omp begin/end declare variant\` is not supported yet; nested context ignored`| ++-----------------------------------------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'#pragma omp declare variant' cannot be applied to the function that was defined already; the original function might be used`| +--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -11493,6 +11789,10 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'`| +------------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`score expressions in the OpenMP context selector need to be constant;` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not and will be ignored`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`OpenMP only allows an ordered construct with the simd clause nested in a simd construct`| +------------------------------------------------------------------------------------------------------------------------------+ @@ -11524,7 +11824,25 @@ This diagnostic is enabled by default. -Wstack-protector ----------------- -This diagnostic flag exists for GCC compatibility, and has no effect in Clang. +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`Unable to protect inline asm that clobbers stack pointer against stack clash`| ++-------------------------------------------------------------------------------------------------------------------+ + + +-Wstack-protector +----------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`Unable to protect inline asm that clobbers stack pointer against stack clash`| ++-------------------------------------------------------------------------------------------------------------------+ + -Wstatic-float-init ------------------- @@ -12229,17 +12547,13 @@ Controls `-Wthread-safety-analysis`_, `-Wthread-safety-attributes`_, `-Wthread-s -------------------------- **Diagnostic text:** -+----------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid capability name '`:placeholder:`A`:diagtext:`'; capability name must be 'mutex' or 'role'`| -+----------------------------------------------------------------------------------------------------------------------------------------+ - +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute requires arguments whose type is annotated with 'capability' attribute; type here is` |nbsp| :placeholder:`B`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute can only be applied in a context annotated with 'capability("mutex")' attribute`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute can only be applied in a context annotated with 'capability' attribute`| ++-----------------------------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`only applies to pointer types; type here is` |nbsp| :placeholder:`B`| @@ -13584,6 +13898,30 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------+ +-Wvoid-pointer-to-enum-cast +--------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + + +-Wvoid-pointer-to-int-cast +-------------------------- +This diagnostic is enabled by default. + +Also controls `-Wvoid-pointer-to-enum-cast`_. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`cast to smaller integer type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`from` |nbsp| :placeholder:`A`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wvoid-ptr-dereference ---------------------- This diagnostic is enabled by default. @@ -13672,3 +14010,10 @@ This diagnostic is enabled by default. +------------------------------------------------------------------------+ +-Wwasm-exception-spec +--------------------- +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`dynamic exception specifications with types are currently ignored in wasm`| ++----------------------------------------------------------------------------------------------------------------+ diff --git a/gnu/llvm/clang/docs/HardwareAssistedAddressSanitizerDesign.rst b/gnu/llvm/clang/docs/HardwareAssistedAddressSanitizerDesign.rst index d02dc00057f..0e6c6902cfb 100644 --- a/gnu/llvm/clang/docs/HardwareAssistedAddressSanitizerDesign.rst +++ b/gnu/llvm/clang/docs/HardwareAssistedAddressSanitizerDesign.rst @@ -67,43 +67,59 @@ Instrumentation Memory Accesses --------------- -All memory accesses are prefixed with an inline instruction sequence that -verifies the tags. Currently, the following sequence is used: +In the majority of cases, memory accesses are prefixed with a call to +an outlined instruction sequence that verifies the tags. The code size +and performance overhead of the call is reduced by using a custom calling +convention that + +* preserves most registers, and +* is specialized to the register containing the address, and the type and + size of the memory access. + +Currently, the following sequence is used: .. code-block:: none // int foo(int *a) { return *a; } - // clang -O2 --target=aarch64-linux -fsanitize=hwaddress -fsanitize-recover=hwaddress -c load.c + // clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - load.c + [...] foo: - 0: 90000008 adrp x8, 0 <__hwasan_shadow> - 4: f9400108 ldr x8, [x8] // shadow base (to be resolved by the loader) - 8: d344dc09 ubfx x9, x0, #4, #52 // shadow offset - c: 38696909 ldrb w9, [x8, x9] // load shadow tag - 10: d378fc08 lsr x8, x0, #56 // extract address tag - 14: 6b09011f cmp w8, w9 // compare tags - 18: 54000061 b.ne 24 // jump to short tag handler on mismatch - 1c: b9400000 ldr w0, [x0] // original load - 20: d65f03c0 ret - 24: 7100413f cmp w9, #0x10 // is this a short tag? - 28: 54000142 b.cs 50 // if not, trap - 2c: 12000c0a and w10, w0, #0xf // find the address's position in the short granule - 30: 11000d4a add w10, w10, #0x3 // adjust to the position of the last byte loaded - 34: 6b09015f cmp w10, w9 // check that position is in bounds - 38: 540000c2 b.cs 50 // if not, trap - 3c: 9240dc09 and x9, x0, #0xffffffffffffff - 40: b2400d29 orr x9, x9, #0xf // compute address of last byte of granule - 44: 39400129 ldrb w9, [x9] // load tag from it - 48: 6b09011f cmp w8, w9 // compare with pointer tag - 4c: 54fffe80 b.eq 1c // if so, continue - 50: d4212440 brk #0x922 // otherwise trap - 54: b9400000 ldr w0, [x0] // tail duplicated original load (to handle recovery) - 58: d65f03c0 ret - -Alternatively, memory accesses are prefixed with a function call. -On AArch64, a function call is used by default in trapping mode. The code size -and performance overhead of the call is reduced by using a custom calling -convention that preserves most registers and is specialized to the register -containing the address and the type and size of the memory access. + str x30, [sp, #-16]! + adrp x9, :got:__hwasan_shadow // load shadow address from GOT into x9 + ldr x9, [x9, :got_lo12:__hwasan_shadow] + bl __hwasan_check_x0_2_short // call outlined tag check + // (arguments: x0 = address, x9 = shadow base; + // "2" encodes the access type and size) + ldr w0, [x0] // inline load + ldr x30, [sp], #16 + ret + + [...] + __hwasan_check_x0_2_short: + ubfx x16, x0, #4, #52 // shadow offset + ldrb w16, [x9, x16] // load shadow tag + cmp x16, x0, lsr #56 // extract address tag, compare with shadow tag + b.ne .Ltmp0 // jump to short tag handler on mismatch + .Ltmp1: + ret + .Ltmp0: + cmp w16, #15 // is this a short tag? + b.hi .Ltmp2 // if not, error + and x17, x0, #0xf // find the address's position in the short granule + add x17, x17, #3 // adjust to the position of the last byte loaded + cmp w16, w17 // check that position is in bounds + b.ls .Ltmp2 // if not, error + orr x16, x0, #0xf // compute address of last byte of granule + ldrb w16, [x16] // load tag from it + cmp x16, x0, lsr #56 // compare with pointer tag + b.eq .Ltmp1 // if matches, continue + .Ltmp2: + stp x0, x1, [sp, #-256]! // save original x0, x1 on stack (they will be overwritten) + stp x29, x30, [sp, #232] // create frame record + mov x1, #2 // set x1 to a constant indicating the type of failure + adrp x16, :got:__hwasan_tag_mismatch_v2 // call runtime function to save remaining registers and report error + ldr x16, [x16, :got_lo12:__hwasan_tag_mismatch_v2] // (load address from GOT to avoid potential register clobbers in delay load handler) + br x16 Heap ---- @@ -131,7 +147,67 @@ but could be optional. Globals ------- -TODO: details. +Most globals in HWASAN instrumented code are tagged. This is accomplished +using the following mechanisms: + + * The address of each global has a static tag associated with it. The first + defined global in a translation unit has a pseudorandom tag associated + with it, based on the hash of the file path. Subsequent global tags are + incremental from the previously-assigned tag. + + * The global's tag is added to its symbol address in the object file's symbol + table. This causes the global's address to be tagged when its address is + taken. + + * When the address of a global is taken directly (i.e. not via the GOT), a special + instruction sequence needs to be used to add the tag to the address, + because the tag would otherwise take the address outside of the small code + model (4GB on AArch64). No changes are required when the address is taken + via the GOT because the address stored in the GOT will contain the tag. + + * An associated ``hwasan_globals`` section is emitted for each tagged global, + which indicates the address of the global, its size and its tag. These + sections are concatenated by the linker into a single ``hwasan_globals`` + section that is enumerated by the runtime (via an ELF note) when a binary + is loaded and the memory is tagged accordingly. + +A complete example is given below: + +.. code-block:: none + + // int x = 1; int *f() { return &x; } + // clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - global.c + + [...] + f: + adrp x0, :pg_hi21_nc:x // set bits 12-63 to upper bits of untagged address + movk x0, #:prel_g3:x+0x100000000 // set bits 48-63 to tag + add x0, x0, :lo12:x // set bits 0-11 to lower bits of address + ret + + [...] + .data + .Lx.hwasan: + .word 1 + + .globl x + .set x, .Lx.hwasan+0x2d00000000000000 + + [...] + .section .note.hwasan.globals,"aG",@note,hwasan.module_ctor,comdat + .Lhwasan.note: + .word 8 // namesz + .word 8 // descsz + .word 3 // NT_LLVM_HWASAN_GLOBALS + .asciz "LLVM\000\000\000" + .word __start_hwasan_globals-.Lhwasan.note + .word __stop_hwasan_globals-.Lhwasan.note + + [...] + .section hwasan_globals,"ao",@progbits,.Lx.hwasan,unique,2 + .Lx.hwasan.descriptor: + .word .Lx.hwasan-.Lx.hwasan.descriptor + .word 0x2d000004 // tag = 0x2d, size = 4 Error reporting --------------- diff --git a/gnu/llvm/clang/docs/HowToSetupToolingForLLVM.rst b/gnu/llvm/clang/docs/HowToSetupToolingForLLVM.rst index dfa199ec595..cbe15abaab3 100644 --- a/gnu/llvm/clang/docs/HowToSetupToolingForLLVM.rst +++ b/gnu/llvm/clang/docs/HowToSetupToolingForLLVM.rst @@ -37,7 +37,7 @@ make a build directory and run CMake from it: If you want to use clang instead of GCC, you can add ``-DCMAKE_C_COMPILER=/path/to/clang -DCMAKE_CXX_COMPILER=/path/to/clang++``. You can also use ``ccmake``, which provides a curses interface to configure -CMake variables for lazy people. +CMake variables. As a result, the new ``compile_commands.json`` file should appear in the current directory. You should link it to the LLVM source tree so that @@ -140,7 +140,7 @@ Examples: return new clang::ASTConsumer(); } -(Experimental) Using Ninja Build System +Using Ninja Build System ======================================= Optionally you can use the `Ninja `_ @@ -197,4 +197,3 @@ Now you are ready to build and test LLVM using Ninja: $ ninja check-all Other target names can be used in the same way as with make. - diff --git a/gnu/llvm/clang/docs/InternalsManual.rst b/gnu/llvm/clang/docs/InternalsManual.rst index 409432efcfb..09aec6df69f 100644 --- a/gnu/llvm/clang/docs/InternalsManual.rst +++ b/gnu/llvm/clang/docs/InternalsManual.rst @@ -2294,9 +2294,10 @@ are created implicitly. The following spellings are accepted: ============ ================================================================ ``GNU`` Spelled with a GNU-style ``__attribute__((attr))`` syntax and placement. - ``CXX11`` Spelled with a C++-style ``[[attr]]`` syntax. If the attribute - is meant to be used by Clang, it should set the namespace to - ``"clang"``. + ``CXX11`` Spelled with a C++-style ``[[attr]]`` syntax with an optional + vendor-specific namespace. + ``C2x`` Spelled with a C-style ``[[attr]]`` syntax with an optional + vendor-specific namespace. ``Declspec`` Spelled with a Microsoft-style ``__declspec(attr)`` syntax. ``Keyword`` The attribute is spelled as a keyword, and required custom parsing. @@ -2304,6 +2305,11 @@ are created implicitly. The following spellings are accepted: the second is a C++-style spelling with the ``gnu`` namespace. Attributes should only specify this spelling for attributes supported by GCC. + ``Clang`` Specifies two or three spellings: the first is a GNU-style + spelling, the second is a C++-style spelling with the ``clang`` + namespace, and the third is an optional C-style spelling with + the ``clang`` namespace. By default, a C-style spelling is + provided. ``Pragma`` The attribute is spelled as a ``#pragma``, and requires custom processing within the preprocessor. If the attribute is meant to be used by Clang, it should set the namespace to ``"clang"``. @@ -2449,6 +2455,9 @@ Attributes that do not require custom semantic handling should set the attributes are assumed to use a semantic handler by default. Attributes without a semantic handler are not given a parsed attribute ``Kind`` enumerator. +"Simple" attributes, that require no custom semantic processing aside from what +is automatically provided, should set the ``SimpleHandler`` field to ``1``. + Target-specific attributes may share a spelling with other attributes in different targets. For instance, the ARM and MSP430 targets both have an attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic @@ -2475,12 +2484,11 @@ Boilerplate All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp `_, and generally starts in the ``ProcessDeclAttribute()`` function. If the -attribute is a "simple" attribute -- meaning that it requires no custom semantic -processing aside from what is automatically provided, add a call to -``handleSimpleAttribute(S, D, Attr);`` to the switch statement. -Otherwise, write a new ``handleYourAttr()`` function, and add that to the switch -statement. Please do not implement handling logic directly in the ``case`` for -the attribute. +attribute has the ``SimpleHandler`` field set to ``1`` then the function to +process the attribute will be automatically generated, and nothing needs to be +done here. Otherwise, write a new ``handleYourAttr()`` function, and add that to +the switch statement. Please do not implement handling logic directly in the +``case`` for the attribute. Unless otherwise specified by the attribute definition, common semantic checking of the parsed attribute is handled automatically. This includes diagnosing diff --git a/gnu/llvm/clang/docs/LTOVisibility.rst b/gnu/llvm/clang/docs/LTOVisibility.rst index 3a60f54e1b9..cdc0b9cc0e1 100644 --- a/gnu/llvm/clang/docs/LTOVisibility.rst +++ b/gnu/llvm/clang/docs/LTOVisibility.rst @@ -35,6 +35,16 @@ other classes receive hidden LTO visibility. Classes with internal linkage (e.g. classes declared in unnamed namespaces) also receive hidden LTO visibility. +During the LTO link, all classes with public LTO visibility will be refined +to hidden LTO visibility when the ``--lto-whole-program-visibility`` lld linker +option is applied (``-plugin-opt=whole-program-visibility`` for gold). This flag +can be used to defer specifying whether classes have hidden LTO visibility until +link time, to allow bitcode objects to be shared by different LTO links. +Due to an implementation limitation, symbols associated with classes with hidden +LTO visibility may still be exported from the binary when using this flag. It is +unsafe to refer to these symbols, and their visibility may be relaxed to hidden +in a future compiler release. + A class defined in a translation unit built without LTO receives public LTO visibility regardless of its object file visibility, linkage or other attributes. diff --git a/gnu/llvm/clang/docs/LanguageExtensions.rst b/gnu/llvm/clang/docs/LanguageExtensions.rst index 456bcb305e3..06ecc186c7d 100644 --- a/gnu/llvm/clang/docs/LanguageExtensions.rst +++ b/gnu/llvm/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + MatrixTypes Introduction ============ @@ -474,10 +475,10 @@ unary operators +, -- yes yes yes -- +,--,*,/,% yes yes yes -- bitwise operators &,|,^,~ yes yes yes -- >>,<< yes yes yes -- -!, &&, || yes -- yes [#]_ -- +!, &&, || yes -- yes -- ==, !=, >, <, >=, <= yes yes yes -- = yes yes yes yes -:? [#]_ yes -- yes -- +?: [#]_ yes -- yes -- sizeof yes yes yes yes C-style cast yes yes yes no reinterpret_cast yes no yes no @@ -487,16 +488,35 @@ const_cast no no no no See also :ref:`langext-__builtin_shufflevector`, :ref:`langext-__builtin_convertvector`. -.. [#] unary operator ! is not implemented, however && and || are. -.. [#] While OpenCL and GCC vectors both implement the comparison operator(?:) as a - 'select', they operate somewhat differently. OpenCL selects based on signedness of - the condition operands, but GCC vectors use normal bool conversions (that is, != 0). +.. [#] ternary operator(?:) has different behaviors depending on condition + operand's vector type. If the condition is a GNU vector (i.e. __vector_size__), + it's only available in C++ and uses normal bool conversions (that is, != 0). + If it's an extension (OpenCL) vector, it's only available in C and OpenCL C. + And it selects base on signedness of the condition operands (OpenCL v1.1 s6.3.9). + +Matrix Types +============ + +Clang provides an extension for matrix types, which is currently being +implemented. See :ref:`the draft specification ` for more details. + +For example, the code below uses the matrix types extension to multiply two 4x4 +float matrices and add the result to a third 4x4 matrix. + +.. code-block:: c++ + + typedef float m4x4_t __attribute__((matrix_type(4, 4))); + + m4x4_t f(m4x4_t a, m4x4_t b, m4x4_t c) { + return a + b * c; + } + Half-Precision Floating Point ============================= -Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and -``_Float16``. These types are supported in all language modes. +Clang supports three half-precision (16-bit) floating point types: ``__fp16``, +``_Float16`` and ``__bf16``. These types are supported in all language modes. ``__fp16`` is supported on every target, as it is purely a storage format; see below. ``_Float16`` is currently only supported on the following targets, with further @@ -508,6 +528,12 @@ targets pending ABI standardization: ``_Float16`` will be supported on more targets as they define ABIs for it. +``__bf16`` is purely a storage format; it is currently only supported on the following targets: +* 32-bit ARM +* 64-bit ARM (AArch64) + +The ``__bf16`` type is only available when supported in hardware. + ``__fp16`` is a storage and interchange format only. This means that values of ``__fp16`` are immediately promoted to (at least) ``float`` when used in arithmetic operations, so that e.g. the result of adding two ``__fp16`` values has type ``float``. @@ -1255,6 +1281,34 @@ the clang implementation are in :doc:`Block-ABI-Apple`. Query for this feature with ``__has_extension(blocks)``. +ASM Goto with Output Constraints +================================ + +In addition to the functionality provided by `GCC's extended +assembly `_, clang +supports output constraints with the `goto` form. + +The goto form of GCC's extended assembly allows the programmer to branch to a C +label from within an inline assembly block. Clang extends this behavior by +allowing the programmer to use output constraints: + +.. code-block:: c++ + + int foo(int x) { + int y; + asm goto("# %0 %1 %l2" : "=r"(y) : "r"(x) : : err); + return y; + err: + return -1; + } + +It's important to note that outputs are valid only on the "fallthrough" branch. +Using outputs on an indirect branch may result in undefined behavior. For +example, in the function above, use of the value assigned to `y` in the `err` +block is undefined behavior. + +Query for this feature with ``__has_extension(gnu_asm_goto_with_outputs)``. + Objective-C Features ==================== @@ -1755,6 +1809,52 @@ controlled state. .. _langext-__builtin_shufflevector: +``__builtin_dump_struct`` +------------------------- + +**Syntax**: + +.. code-block:: c++ + + __builtin_dump_struct(&some_struct, &some_printf_func); + +**Examples**: + +.. code-block:: c++ + + struct S { + int x, y; + float f; + struct T { + int i; + } t; + }; + + void func(struct S *s) { + __builtin_dump_struct(s, &printf); + } + +Example output: + +.. code-block:: none + + struct S { + int i : 100 + int j : 42 + float f : 3.14159 + struct T t : struct T { + int i : 1997 + } + } + +**Description**: + +The '``__builtin_dump_struct``' function is used to print the fields of a simple +structure and their values for debugging purposes. The builtin accepts a pointer +to a structure to dump the fields of, and a pointer to a formatted output +function whose signature must be: ``int (*)(const char *, ...)`` and must +support the format specifiers used by ``printf()``. + ``__builtin_shufflevector`` --------------------------- @@ -2055,21 +2155,32 @@ object that overloads ``operator&``. ``__builtin_operator_new`` and ``__builtin_operator_delete`` ------------------------------------------------------------ -``__builtin_operator_new`` allocates memory just like a non-placement non-class -*new-expression*. This is exactly like directly calling the normal -non-placement ``::operator new``, except that it allows certain optimizations +A call to ``__builtin_operator_new(args)`` is exactly the same as a call to +``::operator new(args)``, except that it allows certain optimizations that the C++ standard does not permit for a direct function call to ``::operator new`` (in particular, removing ``new`` / ``delete`` pairs and -merging allocations). +merging allocations), and that the call is required to resolve to a +`replaceable global allocation function +`_. -Likewise, ``__builtin_operator_delete`` deallocates memory just like a -non-class *delete-expression*, and is exactly like directly calling the normal -``::operator delete``, except that it permits optimizations. Only the unsized -form of ``__builtin_operator_delete`` is currently available. +Likewise, ``__builtin_operator_delete`` is exactly the same as a call to +``::operator delete(args)``, except that it permits optimizations +and that the call is required to resolve to a +`replaceable global deallocation function +`_. These builtins are intended for use in the implementation of ``std::allocator`` and other similar allocation libraries, and are only available in C++. +Query for this feature with ``__has_builtin(__builtin_operator_new)`` or +``__has_builtin(__builtin_operator_delete)``: + + * If the value is at least ``201802L``, the builtins behave as described above. + + * If the value is non-zero, the builtins may not support calling arbitrary + replaceable global (de)allocation functions, but do support calling at least + ``::operator new(size_t)`` and ``::operator delete(void*)``. + ``__builtin_preserve_access_index`` ----------------------------------- @@ -2102,6 +2213,30 @@ argument. int *pb =__builtin_preserve_access_index(&v->c[3].b); __builtin_preserve_access_index(v->j); +``__builtin_unique_stable_name`` +-------------------------------- + +``__builtin_unique_stable_name()`` is a builtin that takes a type or expression and +produces a string literal containing a unique name for the type (or type of the +expression) that is stable across split compilations. + +In cases where the split compilation needs to share a unique token for a type +across the boundary (such as in an offloading situation), this name can be used +for lookup purposes. + +This builtin is superior to RTTI for this purpose for two reasons. First, this +value is computed entirely at compile time, so it can be used in constant +expressions. Second, this value encodes lambda functions based on line-number +rather than the order in which it appears in a function. This is valuable +because it is stable in cases where an unrelated lambda is introduced +conditionally in the same function. + +The current implementation of this builtin uses a slightly modified Itanium +Mangler to produce the unique name. The lambda ordinal is replaced with one or +more line/column pairs in the format ``LINE->COL``, separated with a ``~`` +character. Typically, only one pair will be included, however in the case of +macro expansions the entire macro expansion stack is expressed. + Multiprecision Arithmetic Builtins ---------------------------------- @@ -2145,7 +2280,7 @@ Checked Arithmetic Builtins --------------------------- Clang provides a set of builtins that implement checked arithmetic for security -critical applications in a manner that is fast and easily expressable in C. As +critical applications in a manner that is fast and easily expressible in C. As an example of their usage: .. code-block:: c @@ -2224,10 +2359,11 @@ String builtins --------------- Clang provides constant expression evaluation support for builtins forms of -the following functions from the C standard library ```` header: +the following functions from the C standard library headers +```` and ````: * ``memchr`` -* ``memcmp`` +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) * ``strchr`` * ``strcmp`` * ``strlen`` @@ -2257,9 +2393,49 @@ In addition to the above, one further builtin is provided: constant expressions in C++11 onwards (where a cast from ``void*`` to ``char*`` is disallowed in general). -Support for constant expression evaluation for the above builtins be detected +Constant evaluation support for the ``__builtin_mem*`` functions is provided +only for arrays of ``char``, ``signed char``, ``unsigned char``, or ``char8_t``, +despite these functions accepting an argument of type ``const void*``. + +Support for constant expression evaluation for the above builtins can be detected with ``__has_feature(cxx_constexpr_string_builtins)``. +Memory builtins +--------------- + + * ``__builtin_memcpy_inline`` + +.. code-block:: c + + void __builtin_memcpy_inline(void *dst, const void *src, size_t size); + +``__builtin_memcpy_inline(dst, src, size)`` is identical to +``__builtin_memcpy(dst, src, size)`` except that the generated code is +guaranteed not to call any external functions. See [LLVM IR ‘llvm.memcpy.inline’ +Intrinsic](https://llvm.org/docs/LangRef.html#llvm-memcpy-inline-intrinsic) for +more information. + +Note that the `size` argument must be a compile time constant. + +Clang provides constant expression evaluation support for builtin forms of the +following functions from the C standard library headers +```` and ````: + +* ``memcpy`` +* ``memmove`` +* ``wmemcpy`` +* ``wmemmove`` + +In each case, the builtin form has the name of the C library function prefixed +by ``__builtin_``. + +Constant evaluation support is only provided when the source and destination +are pointers to arrays with the same trivially copyable element type, and the +given size is an exact multiple of the element size that is no greater than +the number of elements accessible through the source and destination operands. + +Constant evaluation support is not yet provided for ``__builtin_memcpy_inline``. + Atomic Min/Max builtins with memory ordering -------------------------------------------- @@ -2521,7 +2697,7 @@ pointers and integers. These builtins can be used to avoid relying on implementation-defined behavior of arithmetic on integers derived from pointers. Additionally, these builtins retain type information and, unlike bitwise -arithmentic, they can perform semantic checking on the alignment value. +arithmetic, they can perform semantic checking on the alignment value. **Syntax**: @@ -3004,16 +3180,36 @@ at the start of a compound statement (excluding comments). When using within a compound statement, the pragma is active within the scope of the compound statement. -Currently, only FP contraction can be controlled with the pragma. ``#pragma -clang fp contract`` specifies whether the compiler should contract a multiply -and an addition (or subtraction) into a fused FMA operation when supported by -the target. +Currently, the following settings can be controlled with this pragma: + +``#pragma clang fp reassociate`` allows control over the reassociation +of floating point expressions. When enabled, this pragma allows the expression +``x + (y + z)`` to be reassociated as ``(x + y) + z``. +Reassociation can also occur across multiple statements. +This pragma can be used to disable reassociation when it is otherwise +enabled for the translation unit with the ``-fassociative-math`` flag. +The pragma can take two values: ``on`` and ``off``. + +.. code-block:: c++ + + float f(float x, float y, float z) + { + // Enable floating point reassociation across statements + #pragma fp reassociate(on) + float t = x + y; + float v = t + z; + } + + +``#pragma clang fp contract`` specifies whether the compiler should +contract a multiply and an addition (or subtraction) into a fused FMA +operation when supported by the target. The pragma can take three values: ``on``, ``fast`` and ``off``. The ``on`` option is identical to using ``#pragma STDC FP_CONTRACT(ON)`` and it allows -fusion as specified the language standard. The ``fast`` option allows fusiong +fusion as specified the language standard. The ``fast`` option allows fusion in cases when the language standard does not make this possible (e.g. across -statements in C) +statements in C). .. code-block:: c++ @@ -3028,6 +3224,41 @@ The pragma can also be used with ``off`` which turns FP contraction off for a section of the code. This can be useful when fast contraction is otherwise enabled for the translation unit with the ``-ffp-contract=fast`` flag. +The ``#pragma float_control`` pragma allows precise floating-point +semantics and floating-point exception behavior to be specified +for a section of the source code. This pragma can only appear at file scope or +at the start of a compound statement (excluding comments). When using within a +compound statement, the pragma is active within the scope of the compound +statement. This pragma is modeled after a Microsoft pragma with the +same spelling and syntax. For pragmas specified at file scope, a stack +is supported so that the ``pragma float_control`` settings can be pushed or popped. + +When ``pragma float_control(precise, on)`` is enabled, the section of code +governed by the pragma uses precise floating point semantics, effectively +``-ffast-math`` is disabled and ``-ffp-contract=on`` +(fused multiply add) is enabled. + +When ``pragma float_control(except, on)`` is enabled, the section of code governed +by the pragma behaves as though the command-line option +``-ffp-exception-behavior=strict`` is enabled, +when ``pragma float_control(precise, off)`` is enabled, the section of code +governed by the pragma behaves as though the command-line option +``-ffp-exception-behavior=ignore`` is enabled. + +The full syntax this pragma supports is +``float_control(except|precise, on|off [, push])`` and +``float_control(push|pop)``. +The ``push`` and ``pop`` forms, including using ``push`` as the optional +third argument, can only occur at file scope. + +.. code-block:: c++ + + for(...) { + // This block will be compiled with -fno-fast-math and -ffp-contract=on + #pragma float_control(precise, on) + a = b[i] * c[i] + e; + } + Specifying an attribute for multiple declarations (#pragma clang attribute) =========================================================================== @@ -3186,6 +3417,9 @@ Clang supports the following match rules: - ``variable(is_global)``: Can be used to apply attributes to global variables only. +- ``variable(is_local)``: Can be used to apply attributes to local variables + only. + - ``variable(is_parameter)``: Can be used to apply attributes to parameters only. @@ -3311,3 +3545,56 @@ Since the size of ``buffer`` can't be known at compile time, Clang will fold ``__builtin_object_size(buffer, 0)`` into ``-1``. However, if this was written as ``__builtin_dynamic_object_size(buffer, 0)``, Clang will fold it into ``size``, providing some extra runtime safety. + +Extended Integer Types +====================== + +Clang supports a set of extended integer types under the syntax ``_ExtInt(N)`` +where ``N`` is an integer that specifies the number of bits that are used to represent +the type, including the sign bit. The keyword ``_ExtInt`` is a type specifier, thus +it can be used in any place a type can, including as a non-type-template-parameter, +as the type of a bitfield, and as the underlying type of an enumeration. + +An extended integer can be declared either signed, or unsigned by using the +``signed``/``unsigned`` keywords. If no sign specifier is used or if the ``signed`` +keyword is used, the extended integer type is a signed integer and can represent +negative values. + +The ``N`` expression is an integer constant expression, which specifies the number +of bits used to represent the type, following normal integer representations for +both signed and unsigned types. Both a signed and unsigned extended integer of the +same ``N`` value will have the same number of bits in its representation. Many +architectures don't have a way of representing non power-of-2 integers, so these +architectures emulate these types using larger integers. In these cases, they are +expected to follow the 'as-if' rule and do math 'as-if' they were done at the +specified number of bits. + +In order to be consistent with the C language specification, and make the extended +integer types useful for their intended purpose, extended integers follow the C +standard integer conversion ranks. An extended integer type has a greater rank than +any integer type with less precision. However, they have lower rank than any +of the built in or other integer types (such as __int128). Usual arithmetic conversions +also work the same, where the smaller ranked integer is converted to the larger. + +The one exception to the C rules for integers for these types is Integer Promotion. +Unary +, -, and ~ operators typically will promote operands to ``int``. Doing these +promotions would inflate the size of required hardware on some platforms, so extended +integer types aren't subject to the integer promotion rules in these cases. + +In languages (such as OpenCL) that define shift by-out-of-range behavior as a mask, +non-power-of-two versions of these types use an unsigned remainder operation to constrain +the value to the proper range, preventing undefined behavior. + +Extended integer types are aligned to the next greatest power-of-2 up to 64 bits. +The size of these types for the purposes of layout and ``sizeof`` are the number of +bits aligned to this calculated alignment. This permits the use of these types in +allocated arrays using common ``sizeof(Array)/sizeof(ElementType)`` pattern. + +Extended integer types work with the C _Atomic type modifier, however only precisions +that are powers-of-2 greater than 8 bit are accepted. + +Extended integer types align with existing calling conventions. They have the same size +and alignment as the smallest basic type that can contain them. Types that are larger +than 64 bits are handled in the same way as _int128 is handled; they are conceptually +treated as struct of register size chunks. They number of chunks are the smallest +number that can contain the types which does not necessarily mean a power-of-2 size. diff --git a/gnu/llvm/clang/docs/LibASTImporter.rst b/gnu/llvm/clang/docs/LibASTImporter.rst index 9c02b6ae76e..bedaf527f5e 100644 --- a/gnu/llvm/clang/docs/LibASTImporter.rst +++ b/gnu/llvm/clang/docs/LibASTImporter.rst @@ -119,7 +119,7 @@ Now we create the Importer and do the import: llvm::Expected ImportedOrErr = Importer.Import(From); The ``Import`` call returns with ``llvm::Expected``, so, we must check for any error. -Please refer to the `error handling `_ documentation for details. +Please refer to the `error handling `_ documentation for details. .. code-block:: cpp diff --git a/gnu/llvm/clang/docs/LibASTMatchersReference.html b/gnu/llvm/clang/docs/LibASTMatchersReference.html index 5bb181b04d3..60ff6ffe605 100644 --- a/gnu/llvm/clang/docs/LibASTMatchersReference.html +++ b/gnu/llvm/clang/docs/LibASTMatchersReference.html @@ -50,7 +50,7 @@ matcher's source documentation.

Within each category the matchers are ordered by node type they match on. -Note that if a matcher can match multiple node types, it will it will appear +Note that if a matcher can match multiple node types, it will appear multiple times. This means that by searching for Matcher<Stmt> you can find all matchers that can be used to match on Stmt nodes.

@@ -502,6 +502,20 @@ in +Matcher<Decl>tagDeclMatcher<TagDecl>... +
Matches tag declarations.
+
+Example matches X, Z, U, S, E
+  class X;
+  template<class T> class Z {};
+  struct S {};
+  union U {};
+  enum E {
+    A, B, C
+  };
+
+ + Matcher<Decl>templateTypeParmDeclMatcher<TemplateTypeParmDecl>...
Matches template type parameter declarations.
 
@@ -662,9 +676,10 @@ Given
 
   #pragma omp parallel default(none)
   #pragma omp parallel default(shared)
+  #pragma omp parallel default(firstprivate)
   #pragma omp parallel
 
-``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``.
+``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and ``default(firstprivate)``.
 
@@ -1003,6 +1018,21 @@ cxxNewExpr() +Matcher<Stmt>cxxNoexceptExprMatcher<CXXNoexceptExpr>... +
Matches noexcept expressions.
+
+Given
+  bool a() noexcept;
+  bool b() noexcept(true);
+  bool c() noexcept(false);
+  bool d() noexcept(noexcept(a()));
+  bool e = noexcept(b()) || noexcept(c());
+cxxNoexceptExpr()
+  matches `noexcept(a())`, `noexcept(b())` and `noexcept(c())`.
+  doesn't match the noexcept specifier in the declarations a, b, c or d.
+
+ + Matcher<Stmt>cxxNullPtrLiteralExprMatcher<CXXNullPtrLiteralExpr>...
Matches nullptr literal.
 
@@ -1197,6 +1227,11 @@ Example matches std::string() +Matcher<Stmt>fixedPointLiteralMatcher<FixedPointLiteral>... +
Matches fixed point literals
+
+ + Matcher<Stmt>floatLiteralMatcher<FloatingLiteral>...
Matches float literals of all sizes / encodings, e.g.
 1.0, 1.0f, 1.0L and 1e10.
@@ -1721,6 +1756,20 @@ decltypeType()
 
+Matcher<Type>deducedTemplateSpecializationTypeMatcher<DeducedTemplateSpecializationType>... +
Matches C++17 deduced template specialization types, e.g. deduced class
+template types.
+
+Given
+  template <typename T>
+  class C { public: C(T); };
+
+  C c(123);
+deducedTemplateSpecializationType() matches the type in the declaration
+of the variable c.
+
+ + Matcher<Type>dependentSizedArrayTypeMatcher<DependentSizedArrayType>...
Matches C++ arrays whose size is a value-dependent expression.
 
@@ -2085,6 +2134,16 @@ Usable as: Any Matcher
 
+Matcher<BinaryOperator>hasAnyOperatorNameStringRef, ..., StringRef +
Matches operator expressions (binary or unary) that have any of the
+specified names.
+
+   hasAnyOperatorName("+", "-")
+ Is equivalent to
+   anyOf(hasOperatorName("+"), hasOperatorName("-"))
+
+ + Matcher<BinaryOperator>hasOperatorNamestd::string Name
Matches the operator Name of operator expressions (binary or
 unary).
@@ -2104,7 +2163,90 @@ Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
 Example 2: matches s1 = s2
            (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
   struct S { S& operator=(const S&); };
-  void x() { S s1, s2; s1 = s2; })
+  void x() { S s1, s2; s1 = s2; }
+
+ + +Matcher<BinaryOperator>isComparisonOperator +
Matches comparison operators.
+
+Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+  if (a == b)
+    a += b;
+
+Example 2: matches s1 < s2
+           (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+  struct S { bool operator<(const S& other); };
+  void x(S s1, S s2) { bool b1 = s1 < s2; }
+
+ + +Matcher<CXXBaseSpecifier>isPrivate +
Matches private C++ declarations and C++ base specifers that specify private
+inheritance.
+
+Examples:
+  class C {
+  public:    int a;
+  protected: int b;
+  private:   int c; // fieldDecl(isPrivate()) matches 'c'
+  };
+
+  struct Base {};
+  struct Derived1 : private Base {}; // matches 'Base'
+  class Derived2 : Base {}; // matches 'Base'
+
+ + +Matcher<CXXBaseSpecifier>isProtected +
Matches protected C++ declarations and C++ base specifers that specify
+protected inheritance.
+
+Examples:
+  class C {
+  public:    int a;
+  protected: int b; // fieldDecl(isProtected()) matches 'b'
+  private:   int c;
+  };
+
+  class Base {};
+  class Derived : protected Base {}; // matches 'Base'
+
+ + +Matcher<CXXBaseSpecifier>isPublic +
Matches public C++ declarations and C++ base specifers that specify public
+inheritance.
+
+Examples:
+  class C {
+  public:    int a; // fieldDecl(isPublic()) matches 'a'
+  protected: int b;
+  private:   int c;
+  };
+
+  class Base {};
+  class Derived1 : public Base {}; // matches 'Base'
+  struct Derived2 : Base {}; // matches 'Base'
+
+ + +Matcher<CXXBaseSpecifier>isVirtual +
Matches declarations of virtual methods and C++ base specifers that specify
+virtual inheritance.
+
+Example:
+  class A {
+   public:
+    virtual void x(); // matches x
+  };
+
+Example:
+  class Base {};
+  class DirectlyDerived : virtual Base {}; // matches Base
+  class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
+
+Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
 
@@ -2495,14 +2637,21 @@ cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. Matcher<CXXMethodDecl>isVirtual -
Matches if the given method declaration is virtual.
+
Matches declarations of virtual methods and C++ base specifers that specify
+virtual inheritance.
 
-Given
+Example:
   class A {
    public:
-    virtual void x();
+    virtual void x(); // matches x
   };
-  matches A::x
+
+Example:
+  class Base {};
+  class DirectlyDerived : virtual Base {}; // matches Base
+  class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
+
+Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
 
@@ -2532,6 +2681,18 @@ cxxNewExpr(isArray())
+Matcher<CXXOperatorCallExpr>hasAnyOverloadedOperatorNameStringRef, ..., StringRef +
Matches overloaded operator names.
+
+Matches overloaded operator names specified in strings without the
+"operator" prefix: e.g. "<<".
+
+  hasAnyOverloadesOperatorName("+", "-")
+Is equivalent to
+  anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
+
+ + Matcher<CXXOperatorCallExpr>hasOverloadedOperatorNameStringRef Name
Matches overloaded operator names.
 
@@ -2563,7 +2724,21 @@ Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
 Example 2: matches s1 = s2
            (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
   struct S { S& operator=(const S&); };
-  void x() { S s1, s2; s1 = s2; })
+  void x() { S s1, s2; s1 = s2; }
+
+ + +Matcher<CXXOperatorCallExpr>isComparisonOperator +
Matches comparison operators.
+
+Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+  if (a == b)
+    a += b;
+
+Example 2: matches s1 < s2
+           (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+  struct S { bool operator<(const S& other); };
+  void x(S s1, S s2) { bool b1 = s1 < s2; }
 
@@ -2697,7 +2872,7 @@ Example: matches the implicit cast around 0 int *p = 0; If the matcher is use from clang-query, CastKind parameter -should be passed as a quoted string. e.g., ofKind("CK_NullToPointer"). +should be passed as a quoted string. e.g., hasCastKind("CK_NullToPointer"). @@ -2833,7 +3008,7 @@ passed as a quoted string. e.g., hasAttr("attr::CUDADevice"). -Matcher<Decl>isExpansionInFileMatchingstd::string RegExp +Matcher<Decl>isExpansionInFileMatchingStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -2845,6 +3020,10 @@ ASTMatcher.h:
   class Y {};
 
 Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
+
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example "IgnoreCase | BasicRegex"
 
@@ -2905,45 +3084,66 @@ cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1. -Matcher<Decl>isPrivate -
Matches private C++ declarations.
+Matcher<Decl>isInstantiated
+
Matches declarations that are template instantiations or are inside
+template instantiations.
 
 Given
+  template<typename T> void A(T t) { T i; }
+  A(0);
+  A(0U);
+functionDecl(isInstantiated())
+  matches 'A(int) {...};' and 'A(unsigned) {...}'.
+
+ + +Matcher<Decl>isPrivate +
Matches private C++ declarations and C++ base specifers that specify private
+inheritance.
+
+Examples:
   class C {
   public:    int a;
   protected: int b;
-  private:   int c;
+  private:   int c; // fieldDecl(isPrivate()) matches 'c'
   };
-fieldDecl(isPrivate())
-  matches 'int c;'
+
+  struct Base {};
+  struct Derived1 : private Base {}; // matches 'Base'
+  class Derived2 : Base {}; // matches 'Base'
 
Matcher<Decl>isProtected -
Matches protected C++ declarations.
+
Matches protected C++ declarations and C++ base specifers that specify
+protected inheritance.
 
-Given
+Examples:
   class C {
   public:    int a;
-  protected: int b;
+  protected: int b; // fieldDecl(isProtected()) matches 'b'
   private:   int c;
   };
-fieldDecl(isProtected())
-  matches 'int b;'
+
+  class Base {};
+  class Derived : protected Base {}; // matches 'Base'
 
Matcher<Decl>isPublic -
Matches public C++ declarations.
+
Matches public C++ declarations and C++ base specifers that specify public
+inheritance.
 
-Given
+Examples:
   class C {
-  public:    int a;
+  public:    int a; // fieldDecl(isPublic()) matches 'a'
   protected: int b;
   private:   int c;
   };
-fieldDecl(isPublic())
-  matches 'int a;'
+
+  class Base {};
+  class Derived1 : public Base {}; // matches 'Base'
+  struct Derived2 : Base {}; // matches 'Base'
 
@@ -3084,6 +3284,18 @@ Usable as: Matcher<

 
 
+Matcher<
FunctionDecl>hasAnyOverloadedOperatorNameStringRef, ..., StringRef +
Matches overloaded operator names.
+
+Matches overloaded operator names specified in strings without the
+"operator" prefix: e.g. "<<".
+
+  hasAnyOverloadesOperatorName("+", "-")
+Is equivalent to
+  anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
+
+ + Matcher<FunctionDecl>hasDynamicExceptionSpec
Matches functions that have a dynamic exception specification.
 
@@ -3473,6 +3685,16 @@ unresolvedMemberExpr(isArrow())
 
+Matcher<NamedDecl>hasAnyNameStringRef, ..., StringRef +
Matches NamedDecl nodes that have any of the specified names.
+
+This matcher is only provided as a performance optimization of hasName.
+    hasAnyName(a, b, c)
+ is equivalent to, but faster than
+    anyOf(hasName(a), hasName(b), hasName(c))
+
+ + Matcher<NamedDecl>hasExternalFormalLinkage
Matches a declaration that has external formal linkage.
 
@@ -3493,7 +3715,7 @@ void f() {}
 
-Matcher<NamedDecl>hasNameconst std::string Name +Matcher<NamedDecl>hasNameStringRef Name
Matches NamedDecl nodes that have the specified name.
 
 Supports specifying enclosing namespaces or classes by prefixing the name
@@ -3508,7 +3730,7 @@ Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
 
-Matcher<NamedDecl>matchesNamestd::string RegExp +Matcher<NamedDecl>matchesNameStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches NamedDecl nodes whose fully qualified names contain
 a substring matched by the given RegExp.
 
@@ -3521,6 +3743,10 @@ Example matches X (regexp == "::X")
 
 Example matches X (regexp is one of "::X", "^foo::.*X", among others)
   namespace foo { namespace bar { class X; } }
+
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example "IgnoreCase | BasicRegex"
 
@@ -3558,6 +3784,7 @@ Given #pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
@@ -3571,11 +3798,26 @@ Given #pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
+Matcher<OMPDefaultClause>isSharedKind +
Matches if the OpenMP ``default`` clause has ``firstprivate`` kind specified.
+
+Given
+
+  #pragma omp parallel
+  #pragma omp parallel default(none)
+  #pragma omp parallel default(shared)
+  #pragma omp parallel default(firstprivate)
+
+``ompDefaultClause(isFirstPrivateKind())`` matches only ``default(firstprivate)``.
+
+ + Matcher<OMPExecutableDirective>isAllowedToContainClauseKindOpenMPClauseKind CKind
Matches if the OpenMP directive is allowed to contain the specified OpenMP
 clause kind.
@@ -3636,6 +3878,17 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
 
+Matcher<ObjCMessageExpr>hasAnySelectorStringRef, ..., StringRef +
Matches when at least one of the supplied string equals to the
+Selector.getAsString()
+
+ matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
+ matches both of the expressions below:
+    [myObj methodA:argA];
+    [myObj methodB:argB];
+
+ + Matcher<ObjCMessageExpr>hasKeywordSelector
Matches when the selector is a keyword selector
 
@@ -3704,12 +3957,16 @@ but not
 
-Matcher<ObjCMessageExpr>matchesSelectorstd::string RegExp +Matcher<ObjCMessageExpr>matchesSelectorStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches ObjC selectors whose name contains
 a substring matched by the given RegExp.
  matcher = objCMessageExpr(matchesSelector("loadHTMLStringmatches the outer message expr in the code below, but NOT the message
  invocation for self.bodyView.
     [self.bodyView loadHTMLString:html baseURL:NULL];
+
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example "IgnoreCase | BasicRegex"
 
@@ -3793,6 +4050,23 @@ is equivalent to parmVarDecl(hasDefaultArgument()).
+Matcher<ParmVarDecl>isAtPositionunsigned N +
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.
+
+
+Given
+
+void f(int a, int b, int c) {
+}
+
+``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+
+``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+
+ + Matcher<QualType>asStringstd::string Name
Matches if the matched type is represented by the given string.
 
@@ -3942,36 +4216,6 @@ functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
 
-Matcher<RecordDecl>isClass -
Matches RecordDecl object that are spelled with "class."
-
-Example matches C, but not S or U.
-  struct S {};
-  class C {};
-  union U {};
-
- - -Matcher<RecordDecl>isStruct -
Matches RecordDecl object that are spelled with "struct."
-
-Example matches S, but not C or U.
-  struct S {};
-  class C {};
-  union U {};
-
- - -Matcher<RecordDecl>isUnion -
Matches RecordDecl object that are spelled with "union."
-
-Example matches U, but not C or S.
-  struct S {};
-  class C {};
-  union U {};
-
- - Matcher<Stmt>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
@@ -4002,7 +4246,18 @@ Stmt has pointer identity in the AST.
 
-Matcher<Stmt>isExpansionInFileMatchingstd::string RegExp +Matcher<Stmt>isExpandedFromMacrollvm::StringRef MacroName +
Matches statements that are (transitively) expanded from the named macro.
+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.
+
+ + +Matcher<Stmt>isExpansionInFileMatchingStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -4014,6 +4269,10 @@ ASTMatcher.h:
   class Y {};
 
 Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
+
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example "IgnoreCase | BasicRegex"
 
@@ -4045,16 +4304,19 @@ Usable as: Matcher<Stmt>isOMPStructuredBlock -
Matches the Stmt AST node that is marked as being the structured-block
-of an OpenMP executable directive.
+Matcher<Stmt>isInTemplateInstantiation
+
Matches statements inside of a template instantiation.
 
 Given
-
-   #pragma omp parallel
-   {}
-
-``stmt(isOMPStructuredBlock()))`` matches ``{}``.
+  int j;
+  template<typename T> void A(T t) { T i; j += 42;}
+  A(0);
+  A(0U);
+declStmt(isInTemplateInstantiation())
+  matches 'int i;' and 'unsigned i'.
+unless(stmt(isInTemplateInstantiation()))
+  will NOT match j += 42; as it's shared between the template definition and
+  instantiation.
 
@@ -4075,6 +4337,17 @@ stringLiteral(hasSize(4))
+Matcher<TagDecl>isClass +
Matches TagDecl object that are spelled with "class."
+
+Example matches C, but not S, U or E.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + Matcher<TagDecl>isDefinition
Matches if a declaration has a body attached.
 
@@ -4097,6 +4370,39 @@ Usable as: Matcher<TagDecl>isEnum
+
Matches TagDecl object that are spelled with "enum."
+
+Example matches E, but not C, S or U.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + +Matcher<TagDecl>isStruct +
Matches TagDecl object that are spelled with "struct."
+
+Example matches S, but not C, U or E.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + +Matcher<TagDecl>isUnion +
Matches TagDecl object that are spelled with "union."
+
+Example matches U, but not C, S or E.
+  struct S {};
+  class C {};
+  union U {};
+  enum E {};
+
+ + Matcher<TemplateArgument>equalsIntegralValuestd::string Value
Matches a TemplateArgument of integral type with a given value.
 
@@ -4137,7 +4443,7 @@ classTemplateSpecializationDecl(templateArgumentCountIs(1))
 
-Matcher<TypeLoc>isExpansionInFileMatchingstd::string RegExp +Matcher<TypeLoc>isExpansionInFileMatchingStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -4149,6 +4455,10 @@ ASTMatcher.h:
   class Y {};
 
 Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
+
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example "IgnoreCase | BasicRegex"
 
@@ -4255,6 +4565,16 @@ should be passed as a quoted string. e.g., ofKind("UETT_SizeOf").
+Matcher<UnaryOperator>hasAnyOperatorNameStringRef, ..., StringRef +
Matches operator expressions (binary or unary) that have any of the
+specified names.
+
+   hasAnyOperatorName("+", "-")
+ Is equivalent to
+   anyOf(hasOperatorName("+"), hasOperatorName("-"))
+
+ + Matcher<UnaryOperator>hasOperatorNamestd::string Name
Matches the operator Name of operator expressions (binary or
 unary).
@@ -4494,56 +4814,6 @@ cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
 Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
 
- -Matcher<internal::Matcher<Decl>>isInstantiated -
Matches declarations that are template instantiations or are inside
-template instantiations.
-
-Given
-  template<typename T> void A(T t) { T i; }
-  A(0);
-  A(0U);
-functionDecl(isInstantiated())
-  matches 'A(int) {...};' and 'A(unsigned) {...}'.
-
- - -Matcher<internal::Matcher<NamedDecl>>hasAnyNameStringRef, ..., StringRef -
Matches NamedDecl nodes that have any of the specified names.
-
-This matcher is only provided as a performance optimization of hasName.
-    hasAnyName(a, b, c)
- is equivalent to, but faster than
-    anyOf(hasName(a), hasName(b), hasName(c))
-
- - -Matcher<internal::Matcher<ObjCMessageExpr>>hasAnySelectorStringRef, ..., StringRef -
Matches when at least one of the supplied string equals to the
-Selector.getAsString()
-
- matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
- matches both of the expressions below:
-    [myObj methodA:argA];
-    [myObj methodB:argB];
-
- - -Matcher<internal::Matcher<Stmt>>isInTemplateInstantiation -
Matches statements inside of a template instantiation.
-
-Given
-  int j;
-  template<typename T> void A(T t) { T i; j += 42;}
-  A(0);
-  A(0U);
-declStmt(isInTemplateInstantiation())
-  matches 'int i;' and 'unsigned i'.
-unless(stmt(isInTemplateInstantiation()))
-  will NOT match j += 42; as it's shared between the template definition and
-  instantiation.
-
- @@ -4581,6 +4851,22 @@ Usable as: Any Matcher +Matcher<*>findAllMatcher<*> Matcher +
Matches if the node or any descendant matches.
+
+Generates results for each match.
+
+For example, in:
+  class A { class B {}; class C {}; };
+The matcher:
+  cxxRecordDecl(hasName("::A"),
+                findAll(cxxRecordDecl(isDefinition()).bind("m")))
+will generate results for A, B and C.
+
+Usable as: Any Matcher
+
+ + Matcher<*>forEachDescendantMatcher<*>
Matches AST nodes that have descendant AST nodes that match the
 provided matcher.
@@ -4689,14 +4975,12 @@ Usable as: Any Matcher
 
-Matcher<*>optionallyMatcher<*>, ..., Matcher<*> -
Matches any node regardless of the submatchers.
+Matcher<*>optionallyMatcher<*>
+
Matches any node regardless of the submatcher.
 
-However, optionally will generate a result binding for each matching
-submatcher.
-
-Useful when additional information which may or may not present about a
-main matching node is desired.
+However, optionally will retain any bindings generated by the submatcher.
+Useful when additional information which may or may not present about a main
+matching node is desired.
 
 For example, in:
   class Foo {
@@ -4715,6 +4999,22 @@ Usable as: Any Matcher
 
+Matcher<*>traverseTraversalKind TK, Matcher<*> InnerMatcher +
Causes all nested matchers to be matched with the specified traversal kind.
+
+Given
+  void foo()
+  {
+      int i = 3.0;
+  }
+The matcher
+  traverse(TK_IgnoreImplicitCastsAndParentheses,
+    varDecl(hasInitializer(floatLiteral().bind("init")))
+  )
+matches the variable declaration with "init" bound to the "3.0".
+
+ + Matcher<AbstractConditionalOperator>hasConditionMatcher<Expr> InnerMatcher
Matches the condition expression of an if statement, for loop,
 switch statement or conditional operator.
@@ -4745,7 +5045,7 @@ Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
 
-Matcher<AddrLabelExpr>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<AddrLabelExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4862,7 +5162,7 @@ Usable as: Matcher<BinaryOperator>hasEitherOperandconst Matcher<Expr>  InnerMatcher
+Matcher<BinaryOperator>hasEitherOperandMatcher<Expr>  InnerMatcher
 
Matches if either the left hand side or the right hand side of a
 binary operator matches.
 
@@ -4876,6 +5176,18 @@ Example matches a (matcher = binaryOperator(hasLHS()))
+Matcher<BinaryOperator>hasOperandsMatcher<Expr> Matcher1, Matcher<Expr> Matcher2 +
Matches if both matchers match with opposite sides of the binary operator.
+
+Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
+                                             integerLiteral(equals(2)))
+  1 + 2 // Match
+  2 + 1 // Match
+  1 + 1 // No match
+  2 + 2 // No match
+
+ + Matcher<BinaryOperator>hasRHSMatcher<Expr> InnerMatcher
Matches the right hand side of binary operator expressions.
 
@@ -4949,6 +5261,33 @@ Usable as: Matcher<CXXBaseSpecifier>hasTypeMatcher<Decl> InnerMatcher
+
Overloaded to match the declaration of the expression's or value
+declaration's type.
+
+In case of a value declaration (for example a variable declaration),
+this resolves one layer of indirection. For example, in the value
+declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
+X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
+declaration of x.
+
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
+ class X {};
+ void y(X &x) { x; X z; }
+ class Y { friend class X; };
+
+Example matches class Derived
+(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
+class Base {};
+class Derived : Base {};
+
+Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
+Matcher<CXXBaseSpecifier>
+
+ + Matcher<CXXConstructExpr>forEachArgumentWithParamMatcher<Expr> ArgMatcher, Matcher<ParmVarDecl> ParamMatcher
Matches all arguments and their respective ParmVarDecl.
 
@@ -4998,7 +5337,7 @@ Example matches y in x(y)
 
-Matcher<CXXConstructExpr>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<CXXConstructExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -5268,6 +5607,16 @@ Example matches A() in the last line
 
+Matcher<CXXNewExpr>hasAnyPlacementArgMatcher<Expr> InnerMatcher +
Matches any placement new expression arguments.
+
+Given:
+  MyClass *p1 = new (Storage) MyClass();
+cxxNewExpr(hasAnyPlacementArg(anything()))
+  matches the expression 'new (Storage, 16) MyClass()'.
+
+ + Matcher<CXXNewExpr>hasArraySizeMatcher<Expr> InnerMatcher
Matches array new expressions with a given array size.
 
@@ -5278,7 +5627,7 @@ cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
 
-Matcher<CXXNewExpr>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<CXXNewExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -5312,6 +5661,46 @@ Usable as: Matcher<CXXNewExpr>hasPlacementArgunsigned Index, Matcher<Expr> InnerMatcher
+
Matches placement new expression arguments.
+
+Given:
+  MyClass *p1 = new (Storage, 16) MyClass();
+cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16))))
+  matches the expression 'new (Storage, 16) MyClass()'.
+
+ + +Matcher<CXXRecordDecl>hasAnyBaseMatcher<CXXBaseSpecifier> BaseSpecMatcher +
Matches C++ classes that have a direct or indirect base matching BaseSpecMatcher.
+
+Example:
+matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
+  class Foo;
+  class Bar : Foo {};
+  class Baz : Bar {};
+  class SpecialBase;
+  class Proxy : SpecialBase {};  // matches Proxy
+  class IndirectlyDerived : Proxy {};  //matches IndirectlyDerived
+
+FIXME: Refactor this and isDerivedFrom to reuse implementation.
+
+ + +Matcher<CXXRecordDecl>hasDirectBaseMatcher<CXXBaseSpecifier> BaseSpecMatcher +
Matches C++ classes that have a direct base matching BaseSpecMatcher.
+
+Example:
+matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
+  class Foo;
+  class Bar : Foo {};
+  class Baz : Bar {};
+  class SpecialBase;
+  class Proxy : SpecialBase {};  // matches Proxy
+  class IndirectlyDerived : Proxy {};  // doesn't match
+
+ + Matcher<CXXRecordDecl>hasMethodMatcher<CXXMethodDecl> InnerMatcher
Matches the first method of a class or struct that satisfies InnerMatcher.
 
@@ -5476,7 +5865,7 @@ Example matches y in x(y)
 
-Matcher<CallExpr>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<CallExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -5623,7 +6012,7 @@ with compoundStmt()
 
-Matcher<DeclRefExpr>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<DeclRefExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -5810,7 +6199,7 @@ declaration of d.
 
-Matcher<EnumType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<EnumType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -5869,7 +6258,13 @@ Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
  void y(X &x) { x; X z; }
  class Y { friend class X; };
 
-Usable as: Matcher<Expr>, Matcher<ValueDecl>
+Example matches class Derived
+(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
+class Base {};
+class Derived : Base {};
+
+Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
+Matcher<CXXBaseSpecifier>
 
@@ -6083,7 +6478,13 @@ Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) void y(X &x) { x; X z; } class Y { friend class X; }; -Usable as: Matcher<Expr>, Matcher<ValueDecl> +Example matches class Derived +(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))) +class Base {}; +class Derived : Base {}; + +Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>, +Matcher<CXXBaseSpecifier>
@@ -6322,7 +6723,7 @@ Example matches y.
-Matcher<InjectedClassNameType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<InjectedClassNameType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -6356,7 +6757,7 @@ Usable as: Matcher<LabelStmt>hasDeclarationconst Matcher<Decl>  InnerMatcher
+Matcher<LabelStmt>hasDeclarationMatcher<Decl>  InnerMatcher
 
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -6417,7 +6818,7 @@ lambdaExpr(hasAnyCapture(anything()))
 
-Matcher<MemberExpr>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<MemberExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -6523,6 +6924,12 @@ nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A")))))
 
+Matcher<NestedNameSpecifierLoc>locMatcher<NestedNameSpecifier> InnerMatcher +
Matches NestedNameSpecifierLocs for which the given inner
+NestedNameSpecifier-matcher matches.
+
+ + Matcher<NestedNameSpecifierLoc>specifiesTypeLocMatcher<TypeLoc> InnerMatcher
Matches nested name specifier locs that specify a type matching the
 given TypeLoc.
@@ -6835,7 +7242,7 @@ declaration of b but varDecl(hasType(qualType(hasCanonicalType(referenceType()))
 
-Matcher<QualType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<QualType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -6917,7 +7324,7 @@ Example matches X &x and const X &y
 
-Matcher<RecordType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<RecordType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -6992,7 +7399,7 @@ with compoundStmt()
 
-Matcher<Stmt>alignOfExprconst Matcher<UnaryExprOrTypeTraitExpr> InnerMatcher +Matcher<Stmt>alignOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher
Same as unaryExprOrTypeTraitExpr, but only matching
 alignof.
 
@@ -7012,7 +7419,7 @@ returnStmt(forFunction(hasName("operator=")))
-Matcher<Stmt>sizeOfExprconst Matcher<UnaryExprOrTypeTraitExpr> InnerMatcher +Matcher<Stmt>sizeOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher
Same as unaryExprOrTypeTraitExpr, but only matching
 sizeof.
 
@@ -7077,7 +7484,7 @@ cxxForRangeStmt(hasInitStatement(anything()))
-Matcher<TagType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<TagType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -7200,7 +7607,7 @@ functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
 
-Matcher<TemplateSpecializationType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<TemplateSpecializationType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -7254,7 +7661,7 @@ functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
 
-Matcher<TemplateTypeParmType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<TemplateTypeParmType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -7288,39 +7695,9 @@ Usable as: Matcher<findAllconst Matcher<T>  Matcher
-
Matches if the node or any descendant matches.
-
-Generates results for each match.
-
-For example, in:
-  class A { class B {}; class C {}; };
-The matcher:
-  cxxRecordDecl(hasName("::A"),
-                findAll(cxxRecordDecl(isDefinition()).bind("m")))
-will generate results for A, B and C.
-
-Usable as: Any Matcher
-
- - -Matcher<T>traverseast_type_traits::TraversalKind TK, const BindableMatcher<T> InnerMatcher -

-
-
-Matcher<T>traverseast_type_traits::TraversalKind TK, const Matcher<T>  InnerMatcher
-
Causes all nested matchers to be matched with the specified traversal kind.
-
-Given
-  void foo()
-  {
-      int i = 3.0;
-  }
-The matcher
-  traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
-    varDecl(hasInitializer(floatLiteral().bind("init")))
-  )
-matches the variable declaration with "init" bound to the "3.0".
+Matcher<TypeLoc>locMatcher<QualType> InnerMatcher
+
Matches TypeLocs for which the given inner
+QualType-matcher matches.
 
@@ -7339,7 +7716,7 @@ Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
-Matcher<TypedefType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<TypedefType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -7422,7 +7799,7 @@ memberExpr(hasObjectExpression(hasType(pointsTo(
 
-Matcher<UnresolvedUsingType>hasDeclarationconst Matcher<Decl> InnerMatcher +Matcher<UnresolvedUsingType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -7495,7 +7872,13 @@ Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
  void y(X &x) { x; X z; }
  class Y { friend class X; };
 
-Usable as: Matcher<Expr>, Matcher<ValueDecl>
+Example matches class Derived
+(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
+class Base {};
+class Derived : Base {};
+
+Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
+Matcher<CXXBaseSpecifier>
 
@@ -7559,18 +7942,6 @@ Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {}
- -Matcher<internal::BindableMatcher<NestedNameSpecifierLoc>>locMatcher<NestedNameSpecifier> InnerMatcher -
Matches NestedNameSpecifierLocs for which the given inner
-NestedNameSpecifier-matcher matches.
-
- - -Matcher<internal::BindableMatcher<TypeLoc>>locMatcher<QualType> InnerMatcher -
Matches TypeLocs for which the given inner
-QualType-matcher matches.
-
- diff --git a/gnu/llvm/clang/docs/LibFormat.rst b/gnu/llvm/clang/docs/LibFormat.rst index 889fbbac8c7..4ea84e658d1 100644 --- a/gnu/llvm/clang/docs/LibFormat.rst +++ b/gnu/llvm/clang/docs/LibFormat.rst @@ -40,7 +40,7 @@ Style Options The style options describe specific formatting options that can be used in order to make `ClangFormat` comply with different style guides. Currently, -two style guides are hard-coded: +several style guides are hard-coded: .. code-block:: c++ @@ -52,6 +52,26 @@ two style guides are hard-coded: /// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml. FormatStyle getGoogleStyle(); + /// Returns a format style complying with Chromium's style guide: + /// https://chromium.googlesource.com/chromium/src/+/master/styleguide/styleguide.md + FormatStyle getChromiumStyle(); + + /// Returns a format style complying with the GNU coding standards: + /// https://www.gnu.org/prep/standards/standards.html + FormatStyle getGNUStyle(); + + /// Returns a format style complying with Mozilla's style guide + /// https://firefox-source-docs.mozilla.org/code-quality/coding-style/index.html + FormatStyle getMozillaStyle(); + + /// Returns a format style complying with Webkit's style guide: + /// https://webkit.org/code-style-guidelines/ + FormatStyle getWebkitStyle(); + + /// Returns a format style complying with Microsoft's style guide: + /// https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference + FormatStyle getMicrosoftStyle(); + These options are also exposed in the :doc:`standalone tools ` through the `-style` option. diff --git a/gnu/llvm/clang/docs/MatrixTypes.rst b/gnu/llvm/clang/docs/MatrixTypes.rst new file mode 100644 index 00000000000..5d022af4412 --- /dev/null +++ b/gnu/llvm/clang/docs/MatrixTypes.rst @@ -0,0 +1,285 @@ +================== +Matrix Types +================== + +.. contents:: + :local: + +.. _matrixtypes: + +Clang provides a C/C++ language extension that allows users to directly express +fixed-size 2-dimensional matrices as language values and perform arithmetic on +them. + +This feature is currently experimental, and both its design and its +implementation are in flux. + +Draft Specification +=================== + +Matrix Type +----------- + +A matrix type is a scalar type with an underlying *element type*, a constant +number of *rows*, and a constant number of *columns*. Matrix types with the same +element type, rows, and columns are the same type. A value of a matrix type +includes storage for ``rows * columns`` values of the *element type*. The +internal layout, overall size and alignment are implementation-defined. + +The maximum of the product of the number of rows and columns is +implementation-defined. If that implementation-defined limit is exceeded, the +program is ill-formed. + +Currently, the element type of a matrix is only permitted to be one of the +following types: + +* an integer type (as in C2x 6.2.5p19), but excluding enumerated types and ``_Bool`` +* the standard floating types ``float`` or ``double`` +* a half-precision floating point type, if one is supported on the target + +Other types may be supported in the future. + +Matrix Type Attribute +--------------------- + +Matrix types can be declared by adding the ``matrix_type`` attribute to the +declaration of a *typedef* (or a C++ alias declaration). The underlying type +of the *typedef* must be a valid matrix element type. The +attribute takes two arguments, both of which must be integer constant +expressions that evaluate to a value greater than zero. The first specifies the +number of rows, and the second specifies the number of columns. The underlying +type of the *typedef* becomes a matrix type with the given dimensions and an +element type of the former underlying type. + +If a declaration of a *typedef-name* has a ``matrix_type`` attribute, then all +declaration of that *typedef-name* shall have a matrix_type attribute with the +same element type, number of rows, and number of columns. + +Standard Conversions +-------------------- + +The standard conversions are extended as follows. Note that these conversions +are intentionally not listed as satisfying the constraints for assignment, +which is to say, they are only permitted as explicit casts, not as implicit +conversions. + +A value of matrix type can be converted to another matrix type if the number of +rows and columns are the same and the value's elements can be converted to the +element type of the result type. The result is a matrix where each element is +the converted corresponding element. + +A value of any real type (as in C2x 6.2.5p17) can be converted to a matrix type +if it can be converted to the element type of the matrix. The result is a +matrix where all elements are the converted original value. + +If the number of rows or columns differ between the original and resulting +type, the program is ill-formed. + + +Arithmetic Conversions +---------------------- + +The usual arithmetic conversions are extended as follows. + +Insert at the start: + +* If both operands are of matrix type, no arithmetic conversion is performed. +* If one operand is of matrix type and the other operand is of a real type, + convert the real type operand to the matrix type + according to the standard conversion rules. + +Matrix Type Element Access Operator +----------------------------------- + +An expression of the form ``E1 [E2] [E3]``, where ``E1`` has matrix type ``cv +M``, is a matrix element access expression. Let ``T`` be the element type +of ``M``, and let ``R`` and ``C`` be the number of rows and columns in ``M`` +respectively. The index expressions shall have integral or unscoped +enumeration type and shall not be uses of the comma operator unless +parenthesized. The first index expression shall evaluate to a +non-negative value less than ``R``, and the second index expression shall +evaluate to a non-negative value less than ``C``, or else the expression has +undefined behavior. If ``E1`` is a prvalue, the result is a prvalue with type +``T`` and is the value of the element at the given row and column in the matrix. +Otherwise, the result is a glvalue with type ``cv T`` and with the same value +category as ``E1`` which refers to the element at the given row and column in +the matrix. + +Programs containing a single subscript expression into a matrix are ill-formed. + +**Note**: We considered providing an expression of the form +``postfix-expression [expression]`` to access columns of a matrix. We think +that such an expression would be problematic once both column and row major +matrixes are supported: depending on the memory layout, either accessing columns +or rows can be done efficiently, but not both. Instead, we propose to provide +builtins to extract rows and columns from a matrix. This makes the operations +more explicit. + +Matrix Type Binary Operators +---------------------------- + +Each matrix type supports the following binary operators: ``+``, ``-`` and ``*``. The ``*`` +operator provides matrix multiplication, while ``+`` and ``-`` are performed +element-wise. There are also scalar versions of the operators, which take a +matrix type and the matrix element type. The operation is applied to all +elements of the matrix using the scalar value. + +For ``BIN_OP`` in ``+``, ``-``, ``*`` given the expression ``M1 BIN_OP M2`` where +at least one of ``M1`` or ``M2`` is of matrix type and, for `*`, the other is of +a real type: + +* The usual arithmetic conversions are applied to ``M1`` and ``M2``. [ Note: if ``M1`` or + ``M2`` are of a real type, they are broadcast to matrices here. — end note ] +* ``M1`` and ``M2`` shall be of the same matrix type. +* The result is equivalent to Res in the following where col is the number of + columns and row is the number of rows in the matrix type: + +.. code-block:: c++ + + decltype(M1) Res; + for (int C = 0; C < col; ++C) + for (int R = 0; R < row; ++R) + Res[R][C] = M1[R][C] BIN_OP M2[R][C]; + +Given the expression ``M1 * M2`` where ``M1`` and ``M2`` are of matrix type: + +* The usual arithmetic conversions are applied to ``M1`` and ``M2``. +* The type of ``M1`` shall have the same number of columns as the type of ``M2`` has + rows. The element types of ``M1`` and ``M2`` shall be the same type. +* The resulting type, ``MTy``, is a matrix type with the common element type, + the number of rows of ``M1`` and the number of columns of ``M2``. +* The result is equivalent to ``Res`` in the following where ``EltTy`` is the + element type of ``MTy``, ``col`` is the number of columns, ``row`` is the + number of rows in ``MTy`` and ``inner`` is the number of columns of ``M1``: + +.. code-block:: c++ + + MTy Res; + for (int C = 0; C < col; ++C) { + for (int R = 0; R < row; ++R) { + EltTy Elt = 0; + for (int K = 0; K < inner; ++K) { + Elt += M1[R][K] * M2[K][C]; + } + Res[R][C] = Elt; + } + +All operations on matrix types match the behavior of the element type with +respect to signed overflows. + +With respect to floating-point contraction, rounding and environment rules, +operations on matrix types match the behavior of the elementwise operations +in the corresponding expansions provided above. + +Operations on floating-point matrices have the same rounding and floating-point +environment behavior as ordinary floating-point operations in the expression's +context. For the purposes of floating-point contraction, all calculations done +as part of a matrix operation are considered intermediate operations, and their +results need not be rounded to the format of the element type until the final +result in the containing expression. This is subject to the normal restrictions +on contraction, such as ``#pragma STDC FP_CONTRACT``. + +For the ``+=``, ``-=`` and ``*=`` operators the semantics match their expanded +variants. + +Matrix Type Builtin Operations +------------------------------ + +Each matrix type supports a collection of builtin expressions that look like +function calls but do not form an overload set. Here they are described as +function declarations with rules for how to construct the argument list types +and return type and the library description elements from +[library.description.structure.specifications]/3 in the C++ standard. + +Definitions: + +* *M*, *M1*, *M2*, *M3* - Matrix types +* *T* - Element type +* *row*, *col* - Row and column arguments respectively. + + +``M2 __builtin_matrix_transpose(M1 matrix)`` + +**Remarks**: The return type is a cv-unqualified matrix type that has the same +element type as ``M1`` and has the the same number of rows as ``M1`` has columns and +the same number of columns as ``M1`` has rows. + +**Returns**: A matrix ``Res`` equivalent to the code below, where ``col`` refers to the +number of columns of ``M``, and ``row`` to the number of rows of ``M``. + +**Effects**: Equivalent to: + +.. code-block:: c++ + + M Res; + for (int C = 0; C < col; ++C) + for (int R = 0; R < row; ++R) + Res[C][R] = matrix[R][C]; + + +``M __builtin_matrix_column_major_load(T *ptr, size_t row, size_t col, size_t columnStride)`` + +**Mandates**: ``row`` and ``col`` shall be integral constants greater than 0. + +**Preconditions**: ``columnStride`` is greater than or equal to ``row``. + +**Remarks**: The return type is a cv-unqualified matrix type with an element +type of the cv-unqualified version of ``T`` and a number of rows and columns equal +to ``row`` and ``col`` respectively. The parameter ``columnStride`` is optional +and if omitted ``row`` is used as ``columnStride``. + +**Returns**: A matrix ``Res`` equivalent to: + +.. code-block:: c++ + + M Res; + for (size_t C = 0; C < col; ++C) { + for (size_t R = 0; R < row; ++K) + Res[R][C] = ptr[R]; + ptr += columnStride + } + + +``void __builtin_matrix_column_major_store(M matrix, T *ptr, size_t columnStride)`` + +**Preconditions**: ``columnStride`` is greater than or equal to the number of rows in ``M``. + +**Remarks**: The type ``T`` is the const-unqualified version of the matrix +argument’s element type. The parameter ``columnStride`` is optional and if +omitted, the number of rows of ``M`` is used as ``columnStride``. + +**Effects**: Equivalent to: + +.. code-block:: c++ + + for (size_t C = 0; C < columns in M; ++C) { + for (size_t R = 0; R < rows in M; ++K) + ptr[R] = matrix[R][C]; + ptr += columnStride + } + + +TODOs +----- + +TODO: Does it make sense to allow M::element_type, M::rows, and M::columns +where M is a matrix type? We don’t support this anywhere else, but it’s +convenient. The alternative is using template deduction to extract this +information. Also add spelling for C. + +Future Work: Initialization syntax. + + +Decisions for the Implementation in Clang +========================================= + +This section details decisions taken for the implementation in Clang and is not +part of the draft specification. + +The elements of a value of a matrix type are laid out in column-major order +without padding. + +We propose to provide a Clang option to override this behavior and allow +contraction of those operations (e.g. *-ffp-contract=matrix*). + +TODO: Specify how matrix values are passed to functions. diff --git a/gnu/llvm/clang/docs/OpenMPSupport.rst b/gnu/llvm/clang/docs/OpenMPSupport.rst index d3050e009a4..000f23141af 100644 --- a/gnu/llvm/clang/docs/OpenMPSupport.rst +++ b/gnu/llvm/clang/docs/OpenMPSupport.rst @@ -131,7 +131,7 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | loop extension | clause: if for SIMD directives | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| loop extension | inclusive scan extension (matching C++17 PSTL) | :none:`unclaimed` | | +| loop extension | inclusive scan extension (matching C++17 PSTL) | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | memory mangagement | memory allocators | :good:`done` | r341687,r357929 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ @@ -149,7 +149,7 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | task extension | clause: depend on the taskwait construct | :part:`worked on` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| task extension | depend objects and detachable tasks | :part:`worked on` | | +| task extension | depend objects and detachable tasks | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | task extension | mutexinoutset dependence-type for tasks | :good:`done` | D53380,D57576 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ @@ -179,6 +179,10 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | clause: device_type | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| device extension | clause: extended device | :good:`done` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| device extension | clause: uses_allocators clause | :good:`done` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | clause: in_reduction | :part:`worked on` | r308768 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | omp_get_device_num() | :part:`worked on` | D54342 | @@ -191,49 +195,59 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | allow access to the reference count (omp_target_is_present) | :part:`worked on` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | requires directive (unified shared memory) | :good:`done` | | +| device extension | requires directive | :part:`partial` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| device extension | clause: unified_shared_memory | :good:`done` | D52625,D52359 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | clause: unified_address, unified_shared_memory | :good:`done` | D52625,D52359 | +| device extension | clause: unified_address | :part:`partial` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | clause: reverse_offload | :none:`unclaimed parts` | D52780 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | clause: atomic_default_mem_order | :none:`unclaimed parts` | D53513 | +| device extension | clause: atomic_default_mem_order | :good:`done` | D53513 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | clause: dynamic_allocators | :none:`unclaimed parts` | D53079 | +| device extension | clause: dynamic_allocators | :part:`unclaimed parts` | D53079 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | user-defined mappers | :part:`worked on` | D56326,D58638,D58523,D58074,D60972,D59474 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | mapping lambda expression | :good:`done` | D51107 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | clause: use_device_addr for target data | :part:`worked on` | | +| device extension | clause: use_device_addr for target data | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device extension | map(replicate) or map(local) when requires unified_shared_me | :part:`worked on` | D55719,D55892 | +| device extension | support close modifier on map clause | :good:`done` | D55719,D55892 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | teams construct on the host device | :part:`worked on` | Clang part is done, r371553. | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device extension | support non-contiguous array sections for target update | :part:`worked on` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| atomic extension | hints for the atomic construct | :part:`worked on` | D51233 | +| device extension | pointer attachment | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| base language | C11 support | :none:`unclaimed` | | +| atomic extension | hints for the atomic construct | :good:`done` | D51233 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| base language | C++11/14/17 support | :part:`worked on` | | +| base language | C11 support | :good:`done` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| base language | C++11/14/17 support | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | base language | lambda support | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extension | array shaping | :none:`unclaimed` | | +| misc extension | array shaping | :good:`done` | D74144 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | misc extension | library shutdown (omp_pause_resource[_all]) | :none:`unclaimed parts` | D55078 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extension | metadirectives | :none:`worked on` | | +| misc extension | metadirectives | :part:`worked on` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| misc extension | conditional modifier for lastprivate clause | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extension | conditional modifier for lastprivate clause | :part:`worked on` | | +| misc extension | iterator and multidependences | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extension | user-defined function variants | :part:`worked on` | D67294, D64095 | +| misc extension | depobj directive and depobj dependency kind | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extensions | pointer/reference to pointer based array reductions | :none:`unclaimed` | | +| misc extension | user-defined function variants | :part:`worked on` | D67294, D64095, D71847, D71830 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extensions | prevent new type definitions in clauses | :none:`unclaimed` | | +| misc extension | pointer/reference to pointer based array reductions | :none:`unclaimed` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| misc extension | prevent new type definitions in clauses | :good:`done` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| memory model extension | memory model update (seq_cst, acq_rel, release, acquire,...) | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ @@ -250,5 +264,9 @@ want to help with the implementation. +==============================+==============================================================+==========================+=======================================================================+ | misc extension | user-defined function variants with #ifdef protection | :part:`worked on` | D71179 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| misc extension | default(firstprivate) & default(private) | :part:`worked on` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | loop extension | Loop tiling transformation | :part:`claimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| device extension | 'present' map type modifier | :part:`claimed` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ diff --git a/gnu/llvm/clang/docs/ReleaseNotes.rst b/gnu/llvm/clang/docs/ReleaseNotes.rst index 4939230a064..0ccaa7a8212 100644 --- a/gnu/llvm/clang/docs/ReleaseNotes.rst +++ b/gnu/llvm/clang/docs/ReleaseNotes.rst @@ -1,5 +1,5 @@ ========================== -Clang 10.0.0 Release Notes +Clang 11.0.0 Release Notes ========================== .. contents:: @@ -8,12 +8,11 @@ Clang 10.0.0 Release Notes Written by the `LLVM Team `_ - Introduction ============ This document contains the release notes for the Clang C/C++/Objective-C -frontend, part of the LLVM Compiler Infrastructure, release 10.0.0. Here we +frontend, part of the LLVM Compiler Infrastructure, release 11.0.0. Here we describe the status of Clang in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM @@ -25,8 +24,7 @@ For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or the `LLVM Web Site `_. - -What's New in Clang 10.0.0? +What's New in Clang 11.0.0? =========================== Some of the major new features and improvements to Clang are listed @@ -34,553 +32,652 @@ here. Generic improvements to Clang as a whole or to its underlying infrastructure are described first, followed by language-specific sections with improvements to Clang's support for those languages. -Major New Features ------------------- -- clang used to run the actual compilation in a subprocess ("clang -cc1"). - Now compilations are done in-process by default. ``-fno-integrated-cc1`` - restores the former behavior. The ``-v`` and ``-###`` flags will print - "(in-process)" when compilations are done in-process. +Recovery AST +------------ -- Concepts support. Clang now supports C++2a Concepts under the -std=c++2a flag. +clang's AST now improves support for representing broken C++ code. This improves +the quality of subsequent diagnostics after an error is encountered. It also +exposes more information to tools like clang-tidy and clangd that consume +clang’s AST, allowing them to be more accurate on broken code. -Improvements to Clang's diagnostics -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +A RecoveryExpr is introduced in clang's AST, marking an expression containing +semantic errors. This preserves the source range and subexpressions of the +broken expression in the AST (rather than discarding the whole expression). -- ``-Wtautological-overlap-compare`` will warn on negative numbers and non-int - types. +For the following invalid code: -- ``-Wtautological-compare`` for self comparisons and - ``-Wtautological-overlap-compare`` will now look through member and array - access to determine if two operand expressions are the same. + .. code-block:: c++ -- ``-Wtautological-bitwise-compare`` is a new warning group. This group has the - current warning which diagnoses the tautological comparison of a bitwise - operation and a constant. The group also has the new warning which diagnoses - when a bitwise-or with a non-negative value is converted to a bool, since - that bool will always be true. + int NoArg(); // Line 1 + int x = NoArg(42); // oops! -- ``-Wbitwise-conditional-parentheses`` will warn on operator precedence issues - when mixing bitwise-and (&) and bitwise-or (|) operator with the - conditional operator (?:). +clang-10 produces the minimal placeholder: -- ``-Wrange-loop-analysis`` got several improvements. It no longer warns about a - copy being made when the result is bound to an rvalue reference. It no longer - warns when an object of a small, trivially copyable type is copied. The - warning now offers fix-its. Excluding ``-Wrange-loop-bind-reference`` it is now - part of ``-Wall``. To reduce the number of false positives the diagnostic is - disabled in macros and template instantiations. + .. code-block:: c++ -- ``-Wmisleading-indentation`` has been added. This warning is similar to the GCC - warning of the same name. It warns about statements that are indented as if - they were part of a if/else/for/while statement but are not semantically - part of that if/else/for/while. + // VarDecl col:5 x 'int' -- ``-Wbitwise-op-parentheses`` and ``-Wlogical-op-parentheses`` are disabled by default. +clang-11 produces a richer AST: -- The new warnings ``-Wc99-designator`` and ``-Wreorder-init-list`` warn about - uses of C99 initializers in C++ mode for cases that are valid in C99 but not - in C++20. + .. code-block:: c++ -- The new warning ``-Wsizeof-array-div`` catches cases like - ``int arr[10]; ...sizeof(arr) / sizeof(short)...`` - (should be ``sizeof(arr) / sizeof(int)``), and the existing warning - ``-Wsizeof-pointer-div`` catches more cases. + // VarDecl col:5 x 'int' cinit + // `-RecoveryExpr '' contains-errors lvalue + // `-UnresolvedLookupExpr '' lvalue (ADL) = 'NoArg' + // `-IntegerLiteral 'int' 42 -- The new warning ``-Wxor-used-as-pow`` warns on cases where it looks like - the xor operator ``^`` is used to be mean exponentiation, e.g. ``2 ^ 16``. +Note that error-dependent types and values may now occur outside a template +context. Tools may need to adjust assumptions about dependent code. -- The new warning ``-Wfinal-dtor-non-final-class`` warns on classes that - have a final destructor but aren't themselves marked final. +This feature is on by default for C++ code, and can be explicitly controlled +with `-Xclang -f[no-]recovery-ast`. + +Improvements to Clang's diagnostics +----------------------------------- -- ``-Wextra`` now enables ``-Wdeprecated-copy``. The warning deprecates - move and copy constructors in classes where an explicit destructor is - declared. This is for compatibility with GCC 9, and forward looking - for a change that's being considered for C++23. You can disable it with - ``-Wno-deprecated-copy``. +- -Wpointer-to-int-cast is a new warning group. This group warns about C-style + casts of pointers to a integer type too small to hold all possible values. +- -Wuninitialized-const-reference is a new warning controlled by + -Wuninitialized. It warns on cases where uninitialized variables are passed + as const reference arguments to a function. + +- ``-Wimplicit-const-int-float-conversion`` (enabled by default) is a new + option controlled by ``-Wimplicit-int-float-conversion``. It warns on + implicit conversion from a floating constant to an integer type. Non-comprehensive list of changes in this release ------------------------------------------------- -* In both C and C++ (C17 ``6.5.6p8``, C++ ``[expr.add]``), pointer arithmetic is - only permitted within arrays. In particular, the behavior of a program is not - defined if it adds a non-zero offset (or in C, any offset) to a null pointer, - or if it forms a null pointer by subtracting an integer from a non-null - pointer, and the LLVM optimizer now uses those guarantees for transformations. - This may lead to unintended behavior in code that performs these operations. - The Undefined Behavior Sanitizer ``-fsanitize=pointer-overflow`` check has - been extended to detect these cases, so that code relying on them can be - detected and fixed. - -* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) has - learned to sanitize pre/post increment/decrement of types with bit width - smaller than ``int``. - -* For X86 target, ``-march=skylake-avx512``, ``-march=icelake-client``, - ``-march=icelake-server``, ``-march=cascadelake``, ``-march=cooperlake`` will default to - not using 512-bit zmm registers in vectorized code unless 512-bit intrinsics - are used in the source code. 512-bit operations are known to cause the CPUs - to run at a lower frequency which can impact performance. This behavior can be - changed by passing ``-mprefer-vector-width=512`` on the command line. - -* Clang now defaults to ``.init_array`` on Linux. It used to use ``.ctors`` if - the found GCC installation is older than 4.7.0. Add ``-fno-use-init-array`` to - get the old behavior (``.ctors``). - -* The behavior of the flag ``-flax-vector-conversions`` has been modified to - more closely match GCC, as described below. In Clang 10 onwards, command lines - specifying this flag do not permit implicit vector bitcasts between integer - vectors and floating-point vectors. Such conversions are still permitted by - default, however, and the default can be explicitly requested with the - Clang-specific flag ``-flax-vector-conversions=all``. In a future release of - Clang, we intend to change the default to ``-fno-lax-vector-conversions``. - -* Improved support for ``octeon`` MIPS-family CPU. Added ``octeon+`` to - the list of of CPUs accepted by the driver. - -* For the WebAssembly target, the ``wasm-opt`` tool will now be run if it is - found in the PATH, which can reduce code size. - -* For the RISC-V target, floating point registers can now be used in inline - assembly constraints. +- For the ARM target, C-language intrinsics are now provided for the full Arm + v8.1-M MVE instruction set. ```` supports the complete API defined + in the Arm C Language Extensions. + +- For the ARM target, C-language intrinsics ```` for the CDE + instruction set are now provided. + +- clang adds support for a set of extended integer types (``_ExtInt(N)``) that + permit non-power of 2 integers, exposing the LLVM integer types. Since a major + motivating use case for these types is to limit 'bit' usage, these types don't + automatically promote to 'int' when operations are done between two + ``ExtInt(N)`` types, instead math occurs at the size of the largest + ``ExtInt(N)`` type. + +- Users of UBSan, PGO, and coverage on Windows will now need to add clang's + library resource directory to their library search path. These features all + use runtime libraries, and Clang provides these libraries in its resource + directory. For example, if LLVM is installed in ``C:\Program Files\LLVM``, + then the profile runtime library will appear at + ``C:\Program Files\LLVM\lib\clang\11.0.0\lib\windows\clang_rt.profile-x86_64.lib``. + To ensure that the linker can find the appropriate library, users should pass + ``/LIBPATH:C:\Program Files\LLVM\lib\clang\11.0.0\lib\windows`` to the + linker. If the user links the program with the ``clang`` or ``clang-cl`` + drivers, the driver will pass this flag for them. + +- Clang's profile files generated through ``-fprofile-instr-generate`` are using + a fixed hashing algorithm that prevents some collision when loading + out-of-date profile informations. Clang can still read old profile files. + +- Clang adds support for the following macros that enable the + C-intrinsics from the `Arm C language extensions for SVE + `_ (version + ``00bet5``, see section 2.1 for the list of intrinsics associated to + each macro): + + + ================================= ================= + Preprocessor macro Target feature + ================================= ================= + ``__ARM_FEATURE_SVE`` ``+sve`` + ``__ARM_FEATURE_SVE_BF16`` ``+sve+bf16`` + ``__ARM_FEATURE_SVE_MATMUL_FP32`` ``+sve+f32mm`` + ``__ARM_FEATURE_SVE_MATMUL_FP64`` ``+sve+f64mm`` + ``__ARM_FEATURE_SVE_MATMUL_INT8`` ``+sve+i8mm`` + ``__ARM_FEATURE_SVE2`` ``+sve2`` + ``__ARM_FEATURE_SVE2_AES`` ``+sve2-aes`` + ``__ARM_FEATURE_SVE2_BITPERM`` ``+sve2-bitperm`` + ``__ARM_FEATURE_SVE2_SHA3`` ``+sve2-sha3`` + ``__ARM_FEATURE_SVE2_SM4`` ``+sve2-sm4`` + ================================= ================= + + The macros enable users to write C/C++ `Vector Length Agnostic + (VLA)` loops, that can be executed on any CPU that implements the + underlying instructions supported by the C intrinsics, independently + of the hardware vector register size. + + For example, the ``__ARM_FEATURE_SVE`` macro is enabled when + targeting AArch64 code generation by setting ``-march=armv8-a+sve`` + on the command line. + + .. code-block:: c + :caption: Example of VLA addition of two arrays with SVE ACLE. + + // Compile with: + // `clang++ -march=armv8a+sve ...` (for c++) + // `clang -stc=c11 -march=armv8a+sve ...` (for c) + #include + + void VLA_add_arrays(double *x, double *y, double *out, unsigned N) { + for (unsigned i = 0; i < N; i += svcntd()) { + svbool_t Pg = svwhilelt_b64(i, N); + svfloat64_t vx = svld1(Pg, &x[i]); + svfloat64_t vy = svld1(Pg, &y[i]); + svfloat64_t vout = svadd_x(Pg, vx, vy); + svst1(Pg, &out[i], vout); + } + } + + Please note that support for lazy binding of SVE function calls is + incomplete. When you interface user code with SVE functions that are + provided through shared libraries, avoid using lazy binding. If you + use lazy binding, the results could be corrupted. + +- ``-O`` maps to ``-O1`` instead of ``-O2``. + (`D79916 `_) + +- In a ``-flto={full,thin}`` link, ``-Os``, ``-Oz`` and ``-Og`` can be used + now. ``-Os`` and ``-Oz`` map to the -O2 pipe line while ``-Og`` maps to the + -O1 pipeline. + (`D79919 `_) + +- ``--coverage`` (gcov) defaults to gcov [4.8,8) compatible format now. + +- On x86, ``-fpic/-fPIC -fno-semantic-interposition`` assumes a global + definition of default visibility non-interposable and allows interprocedural + optimizations. In produced assembly ``-Lfunc$local`` local aliases are created + for global symbols of default visibility. New Compiler Flags ------------------ -- The ``-fgnuc-version=`` flag now controls the value of ``__GNUC__`` and related - macros. This flag does not enable or disable any GCC extensions implemented in - Clang. Setting the version to zero causes Clang to leave ``__GNUC__`` and - other GNU-namespaced macros, such as ``__GXX_WEAK__``, undefined. +- -fstack-clash-protection will provide a protection against the stack clash + attack for x86, s390x and ppc64 architectures through automatic probing of + each page of allocated stack. -- vzeroupper insertion on X86 targets can now be disabled with ``-mno-vzeroupper``. - You can also force vzeroupper insertion to be used on CPUs that normally - wouldn't with ``-mvzeroupper``. +- -ffp-exception-behavior={ignore,maytrap,strict} allows the user to specify + the floating-point exception behavior. The default setting is ``ignore``. -- The ``-fno-concept-satisfaction-caching`` can be used to disable caching for - satisfactions of Concepts. The C++2a draft standard does not currently permit - this caching, but disabling it may incur significant compile-time costs. This - flag is intended for experimentation purposes and may be removed at any time; - please let us know if you encounter a situation where you need to specify this - flag for correct program behavior. +- -ffp-model={precise,strict,fast} provides the user an umbrella option to + simplify access to the many single purpose floating point options. The default + setting is ``precise``. -- The ``-ffixed-xX`` flags now work on RISC-V. These reserve the corresponding - general-purpose registers. +- The default module cache has moved from /tmp to a per-user cache directory. + By default, this is ~/.cache but on some platforms or installations, this + might be elsewhere. The -fmodules-cache-path=... flag continues to work. + +- -fpch-instantiate-templates tries to instantiate templates already while + generating a precompiled header. Such templates do not need to be + instantiated every time the precompiled header is used, which saves compile + time. This may result in an error during the precompiled header generation + if the source header file is not self-contained. This option is enabled + by default for clang-cl. + +- -fpch-codegen and -fpch-debuginfo generate shared code and/or debuginfo + for contents of a precompiled header in a separate object file. This object + file needs to be linked in, but its contents do not need to be generated + for other objects using the precompiled header. This should usually save + compile time. If not using clang-cl, the separate object file needs to + be created explicitly from the precompiled header. + Example of use: -- RISC-V has added ``-mcmodel=medany`` and ``-mcmodel=medlow`` as aliases for - ``-mcmodel=small`` and ``-mcmodel=medium`` respectively. Preprocessor definitions - for ``__riscv_cmodel_medlow`` and ``__riscv_cmodel_medany`` have been corrected. + .. code-block:: console -- ``-fmacro-prefix-map=OLD=NEW`` substitutes directory prefix ``OLD`` for - ``NEW`` in predefined preprocessor macros such as ``__FILE__``. This helps - with reproducible builds that are location independent. The new - ``-ffile-prefix-map`` option is equivalent to specifying both - ``-fdebug-prefix-map`` and ``-fmacro-prefix-map``. + $ clang++ -x c++-header header.h -o header.pch -fpch-codegen -fpch-debuginfo + $ clang++ -c header.pch -o shared.o + $ clang++ -c source.cpp -o source.o -include-pch header.pch + $ clang++ -o binary source.o shared.o + + - Using -fpch-instantiate-templates when generating the precompiled header + usually increases the amount of code/debuginfo that can be shared. + - In some cases, especially when building with optimizations enabled, using + -fpch-codegen may generate so much code in the shared object that compiling + it may be a net loss in build time. + - Since headers may bring in private symbols of other libraries, it may be + sometimes necessary to discard unused symbols (such as by adding + -Wl,--gc-sections on ELF platforms to the linking command, and possibly + adding -fdata-sections -ffunction-sections to the command generating + the shared object). + +- ``-fsanitize-coverage-allowlist`` and ``-fsanitize-coverage-blocklist`` are added. + +- -mtls-size={12,24,32,48} allows selecting the size of the TLS (thread-local + storage) in the local exec TLS model of AArch64, which is the default TLS + model for non-PIC objects. Each value represents 4KB, 16MB (default), 4GB, + and 256TB (needs -mcmodel=large). This allows large/many thread local + variables or a compact/fast code in an executable. + +- -menable-experimental-extension` can be used to enable experimental or + unratified RISC-V extensions, allowing them to be targeted by specifying the + extension name and precise version number in the `-march` string. For these + experimental extensions, there is no expectation of ongoing support - the + compiler support will continue to change until the specification is + finalised. -- ``-fpatchable-function-entry=N[,M]`` is added to generate M NOPs before the - function entry and N-M NOPs after the function entry. This is used by AArch64 - ftrace in the Linux kernel. -- ``-mbranches-within-32B-boundaries`` is added as an x86 assembler mitigation - for Intel's Jump Condition Code Erratum. +Modified Compiler Flags +----------------------- -- -ffp-exception-behavior={ignore,maytrap,strict} allows the user to specify - the floating-point exception behavior. The default setting is ``ignore``. +- -fno-common has been enabled as the default for all targets. Therefore, C + code that uses tentative definitions as definitions of a variable in multiple + translation units will trigger multiple-definition linker errors. Generally, + this occurs when the use of the ``extern`` keyword is neglected in the + declaration of a variable in a header file. In some cases, no specific + translation unit provides a definition of the variable. The previous + behavior can be restored by specifying ``-fcommon``. +- -Wasm-ignored-qualifier (ex. `asm const ("")`) has been removed and replaced + with an error (this matches a recent change in GCC-9). +- -Wasm-file-asm-volatile (ex. `asm volatile ("")` at global scope) has been + removed and replaced with an error (this matches GCC's behavior). +- Duplicate qualifiers on asm statements (ex. `asm volatile volatile ("")`) no + longer produces a warning via -Wduplicate-decl-specifier, but now an error + (this matches GCC's behavior). +- The deprecated argument ``-f[no-]sanitize-recover`` has changed to mean + ``-f[no-]sanitize-recover=all`` instead of + ``-f[no-]sanitize-recover=undefined,integer`` and is no longer deprecated. +- The argument to ``-f[no-]sanitize-trap=...`` is now optional and defaults to + ``all``. +- ``-fno-char8_t`` now disables the ``char8_t`` keyword, not just the use of + ``char8_t`` as the character type of ``u8`` literals. This restores the + Clang 8 behavior that regressed in Clang 9 and 10. +- -print-targets has been added to print the registered targets. +- -mcpu is now supported for RISC-V, and recognises the generic-rv32, + rocket-rv32, sifive-e31, generic-rv64, rocket-rv64, and sifive-u54 target + CPUs. +- ``-fwhole-program-vtables`` (along with ``-flto*``) now prepares all classes for possible whole program visibility if specified during the LTO link. + (`D71913 `_) + +New Pragmas in Clang +-------------------- -- -ffp-model={precise,strict,fast} provides the user an umbrella option to - simplify access to the many single purpose floating point options. The default - setting is ``precise``. +- The ``clang max_tokens_here`` pragma can be used together with + `-Wmax-tokens `_ to emit a warning when + the number of preprocessor tokens exceeds a limit. Such limits can be helpful + in limiting code growth and slow compiles due to large header files. + +Attribute Changes in Clang +-------------------------- -Deprecated Compiler Flags -------------------------- +- Attributes can now be specified by clang plugins. See the + `Clang Plugins `_ documentation for + details. -The following options are deprecated and ignored. They will be removed in -future versions of Clang. +Windows Support +--------------- -- ``-mmpx`` used to enable the ``__MPX__`` preprocessor define for the Intel MPX - instructions. There were no MPX intrinsics. +- Don't warn about `ms_struct may not produce Microsoft-compatible layouts + for classes with base classes or virtual functions` if the option is + enabled globally, as opposed to enabled on a specific class/struct or + on a specific section in the source files. This avoids needing to + couple `-mms-bitfields` with `-Wno-incompatible-ms-struct` if building + C++ code. -- ``-mno-mpx`` used to disable ``-mmpx`` and is the default behavior. +- Enable `-mms-bitfields` by default for MinGW targets, matching a similar + change in GCC 4.7. -- ``-fconcepts-ts`` previously used to enable experimental concepts support. Use - -std=c++2a instead to enable Concepts support. +C Language Changes in Clang +--------------------------- -Modified Compiler Flags ------------------------ +- The default C language standard used when `-std=` is not specified has been + upgraded from gnu11 to gnu17. -- RISC-V now sets the architecture (riscv32/riscv64) based on the value provided - to the ``-march`` flag, overriding the target provided by ``-triple``. +- Clang now supports the GNU C extension `asm inline`; it won't do anything + *yet*, but it will be parsed. -- ``-flax-vector-conversions`` has been split into three different levels of - laxness, and has been updated to match the GCC semantics: +C++ Language Changes in Clang +----------------------------- - - ``-flax-vector-conversions=all``: This is Clang's current default, and - permits implicit vector conversions (performed as bitcasts) between any - two vector types of the same overall bit-width. - Former synonym: ``-flax-vector-conversions`` (Clang <= 9). +- Clang now implements a restriction on giving non-C-compatible anonymous + structs a typedef name for linkage purposes, as described in C++ committee + paper `P1766R1 `. This paper was adopted by the + C++ committee as a Defect Report resolution, so it is applied retroactively + to all C++ standard versions. This affects code such as: - - ``-flax-vector-conversions=integer``: This permits implicit vector - conversions (performed as bitcasts) between any two integer vector types of - the same overall bit-width. - Synonym: ``-flax-vector-conversions`` (Clang >= 10). + .. code-block:: c++ - - ``-flax-vector-conversions=none``: Do not perform any implicit bitcasts - between vector types. - Synonym: ``-fno-lax-vector-conversions``. + typedef struct { + int f() { return 0; } + } S; -- ``-debug-info-kind`` now has an option ``-debug-info-kind=constructor``, - which is one level below ``-debug-info-kind=limited``. This option causes - debug info for classes to be emitted only when a constructor is emitted. + Previous versions of Clang rejected some constructs of this form + (specifically, where the linkage of the type happened to be computed + before the parser reached the typedef name); those cases are still rejected + in Clang 11. In addition, cases that previous versions of Clang did not + reject now produce an extension warning. This warning can be disabled with + the warning flag ``-Wno-non-c-typedef-for-linkage``. -- RISC-V now chooses a slightly different sysroot path and defaults to using - compiler-rt if no GCC installation is detected. + Affected code should be updated to provide a tag name for the anonymous + struct: -- RISC-V now supports multilibs in baremetal environments. This support does not - extend to supporting multilib aliases. + .. code-block:: c++ -Attribute Changes in Clang --------------------------- + struct S { + int f() { return 0; } + }; -- Support was added for function ``__attribute__((target("branch-protection=...")))`` + If the code is shared with a C compilation (for example, if the parts that + are not C-compatible are guarded with ``#ifdef __cplusplus``), the typedef + declaration should be retained, but a tag name should still be provided: -Windows Support ---------------- + .. code-block:: c++ -- Previous Clang versions contained a work-around to avoid an issue with the - standard library headers in Visual Studio 2019 versions prior to 16.3. This - work-around has now been removed, and users of Visual Studio 2019 are - encouraged to upgrade to 16.3 or later, otherwise they may see link errors as - below: + typedef struct S { + int f() { return 0; } + } S; - .. code-block:: console - error LNK2005: "bool const std::_Is_integral" (??$_Is_integral@H@std@@3_NB) already defined +OpenCL Kernel Language Changes in Clang +--------------------------------------- -- The ``.exe`` output suffix is now added implicitly in MinGW mode, when - Clang is running on Windows (matching GCC's behaviour) +- Added extensions from `cl_khr_subgroup_extensions` to clang and the internal + header. -- Fixed handling of TLS variables that are shared between object files - in MinGW environments +- Added rocm device libs linking for AMDGPU. -- The ``-cfguard`` flag now emits Windows Control Flow Guard checks on indirect - function calls. The previous behavior is still available with the - ``-cfguard-nochecks`` flag. These checks can be disabled for specific - functions using the new ``__declspec(guard(nocf))`` modifier. +- Added diagnostic for OpenCL 2.0 blocks used in function arguments. +- Fixed MS mangling for OpenCL 2.0 pipe type specifier. -C++ Language Changes in Clang ------------------------------ +- Improved command line options for fast relaxed math. -- The behaviour of the `gnu_inline` attribute now matches GCC, for cases - where used without the `extern` keyword. As this is a change compared to - how it behaved in previous Clang versions, a warning is emitted for this - combination. +- Improved `atomic_fetch_min/max` functions in the internal header + (`opencl-c.h`). -Objective-C Language Changes in Clang -------------------------------------- +- Improved size of builtin function table for `TableGen`-based internal header + (enabled by `-fdeclare-opencl-builtins`) and added new functionality for + OpenCL 2.0 atomics, pipes, enqueue kernel, `cl_khr_subgroups`, + `cl_arm_integer_dot_product`. -- In both Objective-C and - Objective-C++, ``-Wcompare-distinct-pointer-types`` will now warn when - comparing ObjC ``Class`` with an ObjC instance type pointer. +Changes related to C++ for OpenCL +--------------------------------- - .. code-block:: objc +- Added `addrspace_cast` operator. - Class clz = ...; - MyType *instance = ...; - bool eq = (clz == instance); // Previously undiagnosed, now warns. +- Improved address space deduction in templates. -- Objective-C++ now diagnoses conversions between ``Class`` and ObjC - instance type pointers. Such conversions already emitted an - on-by-default ``-Wincompatible-pointer-types`` warning in Objective-C - mode, but had inadvertently been missed entirely in - Objective-C++. This has been fixed, and they are now diagnosed as - errors, consistent with the usual C++ treatment for conversions - between unrelated pointer types. +- Improved diagnostics of address spaces in nested pointer conversions. - .. code-block:: objc +ABI Changes in Clang +-------------------- - Class clz = ...; - MyType *instance = ...; - clz = instance; // Previously undiagnosed, now an error. - instance = clz; // Previously undiagnosed, now an error. +- For RISC-V, an ABI bug was fixed when passing complex single-precision + floats in RV64 with the hard float ABI. The bug could only be triggered for + function calls that exhaust the available FPRs. - One particular issue you may run into is attempting to use a class - as a key in a dictionary literal. This will now result in an error, - because ``Class`` is not convertible to ``id``. (Note that - this was already a warning in Objective-C mode.) While an arbitrary - ``Class`` object is not guaranteed to implement ``NSCopying``, the - default metaclass implementation does. Therefore, the recommended - solution is to insert an explicit cast to ``id``, which disables the - type-checking here. - .. code-block:: objc +OpenMP Support in Clang +----------------------- - Class cls = ...; +New features for OpenMP 5.0 were implemented. - // Error: cannot convert from Class to id. - NSDictionary* d = @{cls : @"Hello"}; +- OpenMP 5.0 is the default version supported by the compiler. User can switch + to OpenMP 4.5 using ``-fopenmp-version=45`` option. - // Fix: add an explicit cast to 'id'. - NSDictionary* d = @{(id)cls : @"Hello"}; +- Added support for declare variant directive. -OpenCL Kernel Language Changes in Clang ---------------------------------------- +- Improved support of math functions and complex types for NVPTX target. -Generic changes: +- Added support for parallel execution of target regions for NVPTX target. -- Made ``__private`` to be appear explicitly in diagnostics, AST, etc. -- Fixed diagnostics of ``enqueue_kernel``. +- Added support for ``scan`` directives and ``inscan`` modifier in ``reduction`` + clauses. -OpenCL builtin functions: +- Added support for ``iterator`` construct. -- The majority of the OpenCL builtin functions are now available through - the experimental `TableGen` driven ``-fdeclare-opencl-builtins`` option. -- Align the ``enqueue_marker`` declaration in standard ``opencl-c.h`` to the - OpenCL spec. -- Avoid a void pointer cast in the ``CLK_NULL_EVENT`` definition. -- Aligned OpenCL with c11 atomic fetch max/min. +- Added support for ``depobj`` construct. -Changes in C++ for OpenCL: +- Added support for ``detach`` clauses in task-based directives. -- Fixed language mode predefined macros for C++ mode. -- Allow OpenCL C style compound vector initialization. -- Improved destructor support. -- Implemented address space deduction for pointers/references - to arrays and auto variables. -- Added address spaces support for lambdas and ``constexpr``. -- Fixed misc address spaces usages in classes. +- Added support for array shaping operations. +- Added support for cancellation constructs in ``taskloop`` directives. -ABI Changes in Clang --------------------- +- Nonmonotonic modifier is allowed with all schedule kinds. -- GCC passes vectors of __int128 in memory on X86-64. Clang historically - broke the vectors into multiple scalars using two 64-bit values for each - element. Clang now matches the GCC behavior on Linux and NetBSD. You can - switch back to old API behavior with flag: ``-fclang-abi-compat=9.0``. +- Added support for ``task`` and ``default`` modifiers in ``reduction`` clauses. -- RISC-V now chooses a default ``-march=`` and ``-mabi=`` to match (in almost - all cases) the GCC defaults. On baremetal targets, where neither ``-march=`` - nor ``-mabi=`` are specified, Clang now differs from GCC by defaulting to - ``-march=rv32imac`` ``-mabi=ilp32`` or ``-march=rv64imac`` ``-mabi=lp64`` - depending on the architecture in the target triple. These do not always match - the defaults in Clang 9. We strongly suggest that you explicitly pass - ``-march=`` and ``-mabi=`` when compiling for RISC-V, due to how extensible - this architecture is. +- Added support for strides in array sections. -- RISC-V now uses `target-abi` module metadata to encode the chosen psABI. This - ensures that the correct lowering will be done by LLVM when LTO is enabled. +- Added support for ``use_device_addr`` clause. -- An issue with lowering return types in the RISC-V ILP32D psABI has been fixed. +- Added support for ``uses_allocators`` clause. -OpenMP Support in Clang ------------------------ +- Added support for ``defaultmap`` clause. -New features for OpenMP 5.0 were implemented. Use ``-fopenmp-version=50`` option to activate support for OpenMP 5.0. +- Added basic support for ``hint`` clause in ``atomic`` directives. -- Added support for ``device_type`` clause in declare target directive. -- Non-static and non-ordered loops are nonmonotonic by default. -- Teams-based directives can be used as a standalone directive. -- Added support for collapsing of non-rectangular loops. -- Added support for range-based loops. -- Added support for collapsing of imperfectly nested loops. -- Added support for ``master taskloop``, ``parallel master taskloop``, ``master taskloop simd`` and ``parallel master taskloop simd`` directives. -- Added support for ``if`` clauses in simd-based directives. -- Added support for unified shared memory for NVPTX target. -- Added support for nested atomic and simd directives are allowed in sims-based directives. -- Added support for non temporal clauses in sims-based directives. -- Added basic support for conditional lastprivate variables +- Added basic support for ``affinity`` clause. -Other improvements: +- Added basic support for ``ancestor`` modifier in ``device`` clause. -- Added basic analysis for use of the uninitialized variables in clauses. -- Bug fixes. +- Added support for ``default(firstprivate)`` clause. This clause is the part of + upcoming OpenMP 5.1 and can be enabled using ``-fopenmp-version=51`` option. + +- Bug fixes and optimizations. Internal API Changes -------------------- -These are major API changes that have happened since the 9.0.0 release of +These are major API changes that have happened since the 10.0.0 release of Clang. If upgrading an external codebase that uses Clang as a library, this section should help get you past the largest hurdles of upgrading. -- libTooling APIs that transfer ownership of `FrontendAction` objects now pass - them by `unique_ptr`, making the ownership transfer obvious in the type - system. `FrontendActionFactory::create()` now returns a - `unique_ptr`. `runToolOnCode`, `runToolOnCodeWithArgs`, - `ToolInvocation::ToolInvocation()` now take a `unique_ptr`. +- ``RecursiveASTVisitor`` no longer calls separate methods to visit specific + operator kinds. Previously, ``RecursiveASTVisitor`` treated unary, binary, + and compound assignment operators as if they were subclasses of the + corresponding AST node. For example, the binary operator plus was treated as + if it was a ``BinAdd`` subclass of the ``BinaryOperator`` class: during AST + traversal of a ``BinaryOperator`` AST node that had a ``BO_Add`` opcode, + ``RecursiveASTVisitor`` was calling the ``TraverseBinAdd`` method instead of + ``TraverseBinaryOperator``. This feature was contributing a non-trivial + amount of complexity to the implementation of ``RecursiveASTVisitor``, it was + used only in a minor way in Clang, was not tested, and as a result it was + buggy. Furthermore, this feature was creating a non-uniformity in the API. + Since this feature was not documented, it was quite difficult to figure out + how to use ``RecursiveASTVisitor`` to visit operators. + + To update your code to the new uniform API, move the code from separate + visitation methods into methods that correspond to the actual AST node and + perform case analysis based on the operator opcode as needed: + + * ``TraverseUnary*() => TraverseUnaryOperator()`` + * ``WalkUpFromUnary*() => WalkUpFromUnaryOperator()`` + * ``VisitUnary*() => VisiUnaryOperator()`` + * ``TraverseBin*() => TraverseBinaryOperator()`` + * ``WalkUpFromBin*() => WalkUpFromBinaryOperator()`` + * ``VisitBin*() => VisiBinaryOperator()`` + * ``TraverseBin*Assign() => TraverseCompoundAssignOperator()`` + * ``WalkUpFromBin*Assign() => WalkUpFromCompoundAssignOperator()`` + * ``VisitBin*Assign() => VisiCompoundAssignOperator()`` Build System Changes -------------------- -These are major changes to the build system that have happened since the 9.0.0 +These are major changes to the build system that have happened since the 10.0.0 release of Clang. Users of the build system should adjust accordingly. -- In 8.0.0 and below, the install-clang-headers target would install clang's - resource directory headers. This installation is now performed by the - install-clang-resource-headers target. Users of the old install-clang-headers - target should switch to the new install-clang-resource-headers target. The - install-clang-headers target now installs clang's API headers (corresponding - to its libraries), which is consistent with the install-llvm-headers target. - -- In 9.0.0 and later Clang added a new target, clang-cpp, which generates a - shared library comprised of all the clang component libraries and exporting - the clang C++ APIs. Additionally the build system gained the new - "CLANG_LINK_CLANG_DYLIB" option, which defaults Off, and when set to On, will - force clang (and clang-based tools) to link the clang-cpp library instead of - statically linking clang's components. This option will reduce the size of - binary distributions at the expense of compiler performance. - +- clang-tidy and clang-include-fixer are no longer compiled into libclang by + default. You can set ``LIBCLANG_INCLUDE_CLANG_TOOLS_EXTRA=ON`` to undo that, + but it's expected that that setting will go away eventually. If this is + something you need, please reach out to the mailing list to discuss possible + ways forward. clang-format ------------ -- The ``Standard`` style option specifies which version of C++ should be used - when parsing and formatting C++ code. The set of allowed values has changed: - - - ``Latest`` will always enable new C++ language features. - - ``c++03``, ``c++11``, ``c++14``, ``c++17``, ``c++20`` will pin to exactly - that language version. - - ``Auto`` is the default and detects style from the code (this is unchanged). - - The previous values of ``Cpp03`` and ``Cpp11`` are deprecated. Note that - ``Cpp11`` is treated as ``Latest``, as this was always clang-format's - behavior. (One motivation for this change is the new name describes the - behavior better). - -- Clang-format has a new option called ``--dry-run`` or ``-n`` to emit a - warning for clang-format violations. This can be used together - with ``--ferror-limit=N`` to limit the number of warnings per file and ``--Werror`` - to make warnings into errors. - -- Option *IncludeIsMainSourceRegex* has been added to allow for additional - suffixes and file extensions to be considered as a source file - for execution of logic that looks for "main *include* file" to put - it on top. - - By default, clang-format considers *source* files as "main" only when - they end with: ``.c``, ``.cc``, ``.cpp``, ``.c++``, ``.cxx``, - ``.m`` or ``.mm`` extensions. This config option allows to - extend this set of source files considered as "main". - - For example, if this option is configured to ``(Impl\.hpp)$``, - then a file ``ClassImpl.hpp`` is considered "main" (in addition to - ``Class.c``, ``Class.cc``, ``Class.cpp`` and so on) and "main - include file" logic will be executed (with *IncludeIsMainRegex* setting - also being respected in later phase). Without this option set, - ``ClassImpl.hpp`` would not have the main include file put on top - before any other include. - -- Options ``DeriveLineEnding`` and ``UseCRLF`` have been added to allow - clang-format to control the newlines. ``DeriveLineEnding`` is by default - ``true`` and reflects is the existing mechanism, which based is on majority - rule. The new options allows this to be turned off and ``UseCRLF`` to control - the decision as to which sort of line ending to use. - -- Option ``SpaceBeforeSquareBrackets`` has been added to insert a space before - array declarations. +- Option ``IndentExternBlock`` has been added to optionally apply indenting inside ``extern "C"`` and ``extern "C++"`` blocks. + +- ``IndentExternBlock`` option accepts ``AfterExternBlock`` to use the old behavior, as well as Indent and NoIndent options, which map to true and false, respectively. .. code-block:: c++ - int a [5]; vs int a[5]; + Indent: NoIndent: + #ifdef __cplusplus #ifdef __cplusplus + extern "C" { extern "C++" { + #endif #endif + + void f(void); void f(void); -- Clang-format now supports JavaScript null operators. + #ifdef __cplusplus #ifdef __cplusplus + } } + #endif #endif + +- Option ``IndentCaseBlocks`` has been added to support treating the block + following a switch case label as a scope block which gets indented itself. + It helps avoid having the closing bracket align with the switch statement's + closing bracket (when ``IndentCaseLabels`` is ``false``). .. code-block:: c++ - const x = foo ?? default; - const z = foo?.bar?.baz; + switch (fool) { vs. switch (fool) { + case 1: case 1: { + { bar(); + bar(); } break; + } default: { + break; plop(); + default: } + { } + plop(); + } + } -- Option ``AlwaysBreakAfterReturnType`` now manages all operator functions. +- Option ``ObjCBreakBeforeNestedBlockParam`` has been added to optionally apply + linebreaks for function arguments declarations before nested blocks. -libclang --------- +- Option ``InsertTrailingCommas`` can be set to ``TCS_Wrapped`` to insert + trailing commas in container literals (arrays and objects) that wrap across + multiple lines. It is currently only available for JavaScript and disabled by + default (``TCS_None``). -- Various changes to reduce discrepancies in destructor calls between the - generated ``CFG`` and the actual ``codegen``. +- Option ``BraceWrapping.BeforeLambdaBody`` has been added to manage lambda + line break inside function parameter call in Allman style. - In particular: + .. code-block:: c++ + + true: + connect( + []() + { + foo(); + bar(); + }); + + false: + connect([]() { + foo(); + bar(); + }); + +- Option ``AlignConsecutiveBitFields`` has been added to align bit field + declarations across multiple adjacent lines + + .. code-block:: c++ + + true: + bool aaa : 1; + bool a : 1; + bool bb : 1; + + false: + bool aaa : 1; + bool a : 1; + bool bb : 1; - - Respect C++17 copy elision; previously it would generate destructor calls - for elided temporaries, including in initialization and return statements. +- Option ``BraceWrapping.BeforeWhile`` has been added to allow wrapping + before the ```while`` in a do..while loop. By default the value is (``false``) - - Don't generate duplicate destructor calls for statement expressions. + In previous releases ``IndentBraces`` implied ``BraceWrapping.BeforeWhile``. + If using a Custom BraceWrapping style you may need to now set + ``BraceWrapping.BeforeWhile`` to (``true``) to be explicit. + + .. code-block:: c++ - - Fix initialization lists. + true: + do { + foo(); + } + while(1); - - Fix comma operator. + false: + do { + foo(); + } while(1); - - Change printing of implicit destructors to print the type instead of the - class name directly, matching the code for temporary object destructors. - The class name was blank for lambdas. +.. _release-notes-clang-static-analyzer: Static Analyzer --------------- -- New checker: ``alpha.cplusplus.PlacementNew`` to detect whether the storage - provided for default placement new is sufficiently large. +- Improved the analyzer's understanding of inherited C++ constructors. -- New checker: ``fuchsia.HandleChecker`` to detect leaks related to Fuchsia - handles. +- Improved the analyzer's understanding of dynamic class method dispatching in + Objective-C. -- New checker: ``security.insecureAPI.decodeValueOfObjCType`` warns about - potential buffer overflows when using ``[NSCoder decodeValueOfObjCType:at:]`` +- Greatly improved the analyzer's constraint solver by better understanding + when constraints are imposed on multiple symbolic values that are known to be + equal or known to be non-equal. It will now also efficiently reject impossible + if-branches between known comparison expressions. -- ``deadcode.DeadStores`` now warns about nested dead stores. +- Added :ref:`on-demand parsing ` capability to Cross Translation + Unit (CTU) analysis. -- Condition values that are relevant to the occurrence of a bug are far better - explained in bug reports. +- Numerous fixes and improvements for the HTML output. -- Despite still being at an alpha stage, checkers implementing taint analyses - and C++ iterator rules were improved greatly. +- New checker: :ref:`alpha.core.C11Lock ` and + :ref:`alpha.fuchsia.Lock ` checks for their respective + locking APIs. -- Numerous smaller fixes. +- New checker: :ref:`alpha.security.cert.pos.34c ` + finds calls to ``putenv`` where a pointer to an autmoatic variable is passed + as an argument. -.. _release-notes-ubsan: +- New checker: :ref:`webkit.NoUncountedMemberChecker + ` to enforce the existence of virtual + destructors for all uncounted types used as base classes. -Undefined Behavior Sanitizer (UBSan) ------------------------------------- +- New checker: :ref:`webkit.RefCntblBaseVirtualDtor + ` checks that only ref-counted types + are used as class members, not raw pointers and references to uncounted + types. -* The ``pointer-overflow`` check was extended added to catch the cases where - a non-zero offset is applied to a null pointer, or the result of - applying the offset is a null pointer. +- New checker: :ref:`alpha.cplusplus.SmartPtr ` check + for dereference of null smart pointers. - .. code-block:: c++ +- Moved ``PlacementNewChecker`` out of alpha, making it enabled by default. - #include // for intptr_t +- Added support for multi-dimensional variadic arrays in ``core.VLASize``. - static char *getelementpointer_inbounds(char *base, unsigned long offset) { - // Potentially UB. - return base + offset; - } +- Added a check for insufficient storage in array placement new calls, as well + as support for alignment variants to ``cplusplus.PlacementNew``. - char *getelementpointer_unsafe(char *base, unsigned long offset) { - // Always apply offset. UB if base is ``nullptr`` and ``offset`` is not - // zero, or if ``base`` is non-``nullptr`` and ``offset`` is - // ``-reinterpret_cast(base)``. - return getelementpointer_inbounds(base, offset); - } +- While still in alpha, ``alpha.unix.PthreadLock``, the iterator and container + modeling infrastructure, ``alpha.unix.Stream``, and taint analysis were + improved greatly. An ongoing, currently off-by-default improvement was made on + the pre-condition modeling of several functions defined in the POSIX standard. - char *getelementpointer_safe(char *base, unsigned long offset) { - // Cast pointer to integer, perform usual arithmetic addition, - // and cast to pointer. This is legal. - char *computed = - reinterpret_cast(reinterpret_cast(base) + offset); - // If either the pointer becomes non-``nullptr``, or becomes - // ``nullptr``, we must use ``computed`` result. - if (((base == nullptr) && (computed != nullptr)) || - ((base != nullptr) && (computed == nullptr))) - return computed; - // Else we can use ``getelementpointer_inbounds()``. - return getelementpointer_inbounds(base, offset); - } +- Improved the warning messages of several checkers. + +- Fixed a few remaining cases of checkers emitting reports under incorrect + checker names, and employed a few restrictions to more easily identify and + avoid such errors. + +- Moved several non-reporting checkers (those that model, among other things, + standard functions, but emit no diagnostics) to be listed under + ``-analyzer-checker-help-developer`` instead of ``-analyzer-checker-help``. + Manually enabling or disabling checkers found on this list is not supported + in production. -Changes deferred to Clang-11 release ------------------------------------- +- Numerous fixes for crashes, false positives and false negatives in + ``unix.Malloc``, ``osx.cocoa.NSError``, and several other checkers. -- The next release of clang (clang-11) will upgrade the default C language - standard used if not specified via command line from gnu11 to gnu17. +- Implemented a dockerized testing system to more easily determine the + correctness and performance impact of a change to the static analyzer itself. + The currently beta-version tool is found in + ``(llvm-project repository)/clang/utils/analyzer/SATest.py``. + +.. _release-notes-ubsan: Additional Information diff --git a/gnu/llvm/clang/docs/SanitizerCoverage.rst b/gnu/llvm/clang/docs/SanitizerCoverage.rst index c7cd853dd66..4c8ef7509cb 100644 --- a/gnu/llvm/clang/docs/SanitizerCoverage.rst +++ b/gnu/llvm/clang/docs/SanitizerCoverage.rst @@ -27,7 +27,7 @@ on every edge: Every edge will have its own `guard_variable` (uint32_t). -The compler will also insert calls to a module constructor: +The compiler will also insert calls to a module constructor: .. code-block:: c++ @@ -139,6 +139,28 @@ Users need to implement a single function to capture the counters at startup. // Capture this array in order to read/modify the counters. } + +Inline bool-flag +================ + +**Experimental, may change or disappear in future** + +With ``-fsanitize-coverage=inline-bool-flag`` the compiler will insert +setting an inline boolean to true on every edge. +This is similar to ``-fsanitize-coverage=inline-8bit-counter`` but instead of +an increment of a counter, it just sets a boolean to true. + +Users need to implement a single function to capture the flags at startup. + +.. code-block:: c++ + + extern "C" + void __sanitizer_cov_bool_flag_init(bool *start, bool *end) { + // [start,end) is the array of boolean flags created for the current DSO. + // Capture this array in order to read/modify the flags. + } + + PC-Table ======== @@ -150,8 +172,8 @@ significant binary size overhead. For more information, see `Bug 34636 `_. With ``-fsanitize-coverage=pc-table`` the compiler will create a table of -instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters`` or -``-fsanitize-coverage=trace-pc-guard``. +instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters``, +or ``-fsanitize-coverage=inline-bool-flag``, or ``-fsanitize-coverage=trace-pc-guard``. Users need to implement a single function to capture the PC table at startup: @@ -164,8 +186,9 @@ Users need to implement a single function to capture the PC table at startup: // pairs [PC,PCFlags] for every instrumented block in the current DSO. // Capture this array in order to read the PCs and their Flags. // The number of PCs and PCFlags for a given DSO is the same as the number - // of 8-bit counters (-fsanitize-coverage=inline-8bit-counters) or - // trace_pc_guard callbacks (-fsanitize-coverage=trace-pc-guard) + // of 8-bit counters (-fsanitize-coverage=inline-8bit-counters), or + // boolean flags (-fsanitize-coverage=inline=bool-flags), or trace_pc_guard + // callbacks (-fsanitize-coverage=trace-pc-guard). // A PCFlags describes the basic block: // * bit0: 1 if the block is the function entry block, 0 otherwise. } @@ -289,6 +312,58 @@ will not be instrumented. // for every non-constant array index. void __sanitizer_cov_trace_gep(uintptr_t Idx); +Partially disabling instrumentation +=================================== + +It is sometimes useful to tell SanitizerCoverage to instrument only a subset of the +functions in your target. +With ``-fsanitize-coverage-allowlist=allowlist.txt`` +and ``-fsanitize-coverage-blocklist=blocklist.txt``, +you can specify such a subset through the combination of a allowlist and a blocklist. + +SanitizerCoverage will only instrument functions that satisfy two conditions. +First, the function should belong to a source file with a path that is both allowlisted +and not blocklisted. +Second, the function should have a mangled name that is both allowlisted and not blocklisted. + +The allowlist and blocklist format is similar to that of the sanitizer blocklist format. +The default allowlist will match every source file and every function. +The default blocklist will match no source file and no function. + +A common use case is to have the allowlist list folders or source files for which you want +instrumentation and allow all function names, while the blocklist will opt out some specific +files or functions that the allowlist loosely allowed. + +Here is an example allowlist: + +.. code-block:: none + + # Enable instrumentation for a whole folder + src:bar/* + # Enable instrumentation for a specific source file + src:foo/a.cpp + # Enable instrumentation for all functions in those files + fun:* + +And an example blocklist: + +.. code-block:: none + + # Disable instrumentation for a specific source file that the allowlist allowed + src:bar/b.cpp + # Disable instrumentation for a specific function that the allowlist allowed + fun:*myFunc* + +The use of ``*`` wildcards above is required because function names are matched after mangling. +Without the wildcards, one would have to write the whole mangled name. + +Be careful that the paths of source files are matched exactly as they are provided on the clang +command line. +For example, the allowlist above would include file ``bar/b.cpp`` if the path was provided +exactly like this, but would it would fail to include it with other ways to refer to the same +file such as ``./bar/b.cpp``, or ``bar\b.cpp`` on Windows. +So, please make sure to always double check that your lists are correctly applied. + Default implementation ====================== @@ -357,7 +432,7 @@ Sancov matches these files using module names and binaries file names. -symbolize - Symbolizes the report. Options - -blacklist= - Blacklist file (sanitizer blacklist format). + -blocklist= - Blocklist file (sanitizer blocklist format). -demangle - Print demangled function name. -strip_path_prefix= - Strip this prefix from file paths in reports @@ -376,7 +451,7 @@ to produce a ``.symcov`` file first: sancov -symbolize my_program.123.sancov my_program > my_program.123.symcov -The ``.symcov`` file can be browsed overlayed over the source code by +The ``.symcov`` file can be browsed overlaid over the source code by running ``tools/sancov/coverage-report-server.py`` script that will start an HTTP server. diff --git a/gnu/llvm/clang/docs/SourceBasedCodeCoverage.rst b/gnu/llvm/clang/docs/SourceBasedCodeCoverage.rst index 7e711819be3..0e9c364fbf6 100644 --- a/gnu/llvm/clang/docs/SourceBasedCodeCoverage.rst +++ b/gnu/llvm/clang/docs/SourceBasedCodeCoverage.rst @@ -92,15 +92,42 @@ directory structure will be created. Additionally, the following special instrumented program crashes, or is killed by a signal, perfect coverage information can still be recovered. Continuous mode does not support value profiling for PGO, and is only supported on Darwin at the moment. Support for - Linux may be mostly complete but requires testing, and support for - Fuchsia/Windows may require more extensive changes: please get involved if - you are interested in porting this feature. + Linux may be mostly complete but requires testing, and support for Windows + may require more extensive changes: please get involved if you are interested + in porting this feature. .. code-block:: console # Step 2: Run the program. % LLVM_PROFILE_FILE="foo.profraw" ./foo +Note that continuous mode is also used on Fuchsia where it's the only supported +mode, but the implementation is different. The Darwin and Linux implementation +relies on padding and the ability to map a file over the existing memory +mapping which is generally only available on POSIX systems and isn't suitable +for other platforms. + +On Fuchsia, we rely on the ability to relocate counters at runtime using a +level of indirection. On every counter access, we add a bias to the counter +address. This bias is stored in ``__llvm_profile_counter_bias`` symbol that's +provided by the profile runtime and is initially set to zero, meaning no +relocation. The runtime can map the profile into memory at arbitrary locations, +and set bias to the offset between the original and the new counter location, +at which point every subsequent counter access will be to the new location, +which allows updating profile directly akin to the continuous mode. + +The advantage of this approach is that doesn't require any special OS support. +The disadvantage is the extra overhead due to additional instructions required +for each counter access (overhead both in terms of binary size and performance) +plus duplication of counters (i.e. one copy in the binary itself and another +copy that's mapped into memory). This implementation can be also enabled for +other platforms by passing the ``-runtime-counter-relocation`` option to the +backend during compilation. + +.. code-block:: console + + % clang++ -fprofile-instr-generate -fcoverage-mapping -mllvm -runtime-counter-relocation foo.cc -o foo + Creating coverage reports ========================= diff --git a/gnu/llvm/clang/docs/ThinLTO.rst b/gnu/llvm/clang/docs/ThinLTO.rst index 2d5d0a71fa6..528530c5ae9 100644 --- a/gnu/llvm/clang/docs/ThinLTO.rst +++ b/gnu/llvm/clang/docs/ThinLTO.rst @@ -194,7 +194,8 @@ Possible key-value pairs are: Clang Bootstrap --------------- -To bootstrap clang/LLVM with ThinLTO, follow these steps: +To `bootstrap clang/LLVM `_ +with ThinLTO, follow these steps: 1. The host compiler_ must be a version of clang that supports ThinLTO. #. The host linker_ must support ThinLTO (and in the case of gold, must be @@ -225,7 +226,7 @@ To bootstrap clang/LLVM with ThinLTO, follow these steps: ``CMAKE_EXE_LINKER_FLAGS:STRING=``. Note the configure may fail if linker plugin options are instead specified directly in the previous step. -The `BOOTSTRAP_LLVM_ENABLE_LTO=Thin`` will enable ThinLTO for stage 2 and +The ``BOOTSTRAP_LLVM_ENABLE_LTO=Thin`` will enable ThinLTO for stage 2 and stage 3 in case the compiler used for stage 1 does not support the ThinLTO option. diff --git a/gnu/llvm/clang/docs/UndefinedBehaviorSanitizer.rst b/gnu/llvm/clang/docs/UndefinedBehaviorSanitizer.rst index 0f6a42a2113..76676dfce95 100644 --- a/gnu/llvm/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/gnu/llvm/clang/docs/UndefinedBehaviorSanitizer.rst @@ -54,6 +54,10 @@ and define the desired behavior for each kind of check: * ``-fno-sanitize-recover=...``: print a verbose error report and exit the program; * ``-fsanitize-trap=...``: execute a trap instruction (doesn't require UBSan run-time support). +Note that the ``trap`` / ``recover`` options do not enable the corresponding +sanitizer, and in general need to be accompanied by a suitable ``-fsanitize=`` +flag. + For example if you compile/link your program as: .. code-block:: console @@ -77,7 +81,9 @@ Available checks are: ``true`` nor ``false``. - ``-fsanitize=builtin``: Passing invalid values to compiler builtins. - ``-fsanitize=bounds``: Out of bounds array indexing, in cases - where the array bound can be statically determined. + where the array bound can be statically determined. The check includes + ``-fsanitize=array-bounds`` and ``-fsanitize=local-bounds``. Note that + ``-fsanitize=local-bounds`` is not included in ``-fsanitize=undefined``. - ``-fsanitize=enum``: Load of a value of an enumerated type which is not in the range of representable values for that enumerated type. @@ -121,6 +127,10 @@ Available checks are: is annotated with ``_Nonnull``. - ``-fsanitize=nullability-return``: Returning null from a function with a return type annotated with ``_Nonnull``. + - ``-fsanitize=objc-cast``: Invalid implicit cast of an ObjC object pointer + to an incompatible type. This is often unintentional, but is not undefined + behavior, therefore the check is not a part of the ``undefined`` group. + Currently only supported on Darwin. - ``-fsanitize=object-size``: An attempt to potentially use bytes which the optimizer can determine are not part of the object being accessed. This will also detect some types of undefined behavior that may not @@ -169,7 +179,8 @@ Available checks are: You can also use the following check groups: - ``-fsanitize=undefined``: All of the checks listed above other than ``float-divide-by-zero``, ``unsigned-integer-overflow``, - ``implicit-conversion``, and the ``nullability-*`` group of checks. + ``implicit-conversion``, ``local-bounds`` and the ``nullability-*`` group + of checks. - ``-fsanitize=undefined-trap``: Deprecated alias of ``-fsanitize=undefined``. - ``-fsanitize=implicit-integer-truncation``: Catches lossy integral @@ -198,7 +209,7 @@ You can also use the following check groups: Volatile -------- -The ``null``, ``alignment``, ``object-size``, and ``vptr`` checks do not apply +The ``null``, ``alignment``, ``object-size``, ``local-bounds``, and ``vptr`` checks do not apply to pointers to types with the ``volatile`` qualifier. Minimal Runtime diff --git a/gnu/llvm/clang/docs/UsersManual.rst b/gnu/llvm/clang/docs/UsersManual.rst index 07157b9ad5f..8615a77596b 100644 --- a/gnu/llvm/clang/docs/UsersManual.rst +++ b/gnu/llvm/clang/docs/UsersManual.rst @@ -80,7 +80,7 @@ Basic Usage Intro to how to use a C compiler for newbies. compile + link compile then link debug info enabling optimizations -picking a language to use, defaults to C11 by default. Autosenses based +picking a language to use, defaults to C17 by default. Autosenses based on extension. using a makefile Command Line Options @@ -1220,7 +1220,7 @@ are listed below. * ``-fno-math-errno`` - * ``-ffinite-math`` + * ``-ffinite-math-only`` * ``-fassociative-math`` @@ -1306,14 +1306,14 @@ are listed below. **-f[no-]honor-infinities** If both ``-fno-honor-infinities`` and ``-fno-honor-nans`` are used, - has the same effect as specifying ``-ffinite-math``. + has the same effect as specifying ``-ffinite-math-only``. .. _opt_fhonor-nans: **-f[no-]honor-nans** If both ``-fno-honor-infinities`` and ``-fno-honor-nans`` are used, - has the same effect as specifying ``-ffinite-math``. + has the same effect as specifying ``-ffinite-math-only``. .. _opt_fsigned-zeros: @@ -1351,9 +1351,9 @@ are listed below. Defaults to ``-fno-unsafe-math-optimizations``. -.. _opt_ffinite-math: +.. _opt_ffinite-math-only: -**-f[no-]finite-math** +**-f[no-]finite-math-only** Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf. This defines the ``__FINITE_MATH_ONLY__`` preprocessor macro. @@ -1362,7 +1362,7 @@ are listed below. * ``-fno-honor-infinities`` * ``-fno-honor-nans`` - Defaults to ``-fno-finite-math``. + Defaults to ``-fno-finite-math-only``. .. _opt_frounding-math: @@ -1466,7 +1466,7 @@ are listed below. **-f[no-]sanitize-recover=check1,check2,...** -**-f[no-]sanitize-recover=all** +**-f[no-]sanitize-recover[=all]** Controls which checks enabled by ``-fsanitize=`` flag are non-fatal. If the check is fatal, program will halt after the first error @@ -1492,6 +1492,8 @@ are listed below. **-f[no-]sanitize-trap=check1,check2,...** +**-f[no-]sanitize-trap[=all]** + Controls which checks enabled by the ``-fsanitize=`` flag trap. This option is intended for use in cases where the sanitizer runtime cannot be used (for instance, when building libc or a kernel module), or where @@ -1499,9 +1501,7 @@ are listed below. This flag is only compatible with :doc:`control flow integrity ` schemes and :doc:`UndefinedBehaviorSanitizer` - checks other than ``vptr``. If this flag - is supplied together with ``-fsanitize=undefined``, the ``vptr`` sanitizer - will be implicitly disabled. + checks other than ``vptr``. This flag is enabled by default for sanitizers in the ``cfi`` group. @@ -1677,6 +1677,65 @@ are listed below. on ELF targets when using the integrated assembler. This flag currently only has an effect on ELF targets. +**-f[no]-unique-internal-linkage-names** + + Controls whether Clang emits a unique (best-effort) symbol name for internal + linkage symbols. When this option is set, compiler hashes the main source + file path from the command line and appends it to all internal symbols. If a + program contains multiple objects compiled with the same command-line source + file path, the symbols are not guaranteed to be unique. This option is + particularly useful in attributing profile information to the correct + function when multiple functions with the same private linkage name exist + in the binary. + + It should be noted that this option cannot guarantee uniqueness and the + following is an example where it is not unique when two modules contain + symbols with the same private linkage name: + + .. code-block:: console + + $ cd $P/foo && clang -c -funique-internal-linkage-names name_conflict.c + $ cd $P/bar && clang -c -funique-internal-linkage-names name_conflict.c + $ cd $P && clang foo/name_conflict.o && bar/name_conflict.o + +**-fbasic-block-sections=[labels, all, list=, none]** + + Controls whether Clang emits a label for each basic block. Further, with + values "all" and "list=arg", each basic block or a subset of basic blocks + can be placed in its own unique section. + + With the ``list=`` option, a file containing the subset of basic blocks + that need to placed in unique sections can be specified. The format of the + file is as follows. For example, ``list=spec.txt`` where ``spec.txt`` is the + following: + + :: + + !foo + !!2 + !_Z3barv + + will place the machine basic block with ``id 2`` in function ``foo`` in a + unique section. It will also place all basic blocks of functions ``bar`` + in unique sections. + + Further, section clusters can also be specified using the ``list=`` + option. For example, ``list=spec.txt`` where ``spec.txt`` contains: + + :: + + !foo + !!1 !!3 !!5 + !!2 !!4 !!6 + + will create two unique sections for function ``foo`` with the first + containing the odd numbered basic blocks and the second containing the + even numbered basic blocks. + + Basic block sections allow the linker to reorder basic blocks and enables + link-time optimizations like whole program inter-procedural basic block + reordering. + Profile Guided Optimization --------------------------- @@ -2399,10 +2458,10 @@ See :doc:`LanguageExtensions`. Differences between various standard modes ------------------------------------------ -clang supports the -std option, which changes what language mode clang -uses. The supported modes for C are c89, gnu89, c99, gnu99, c11, gnu11, -c17, gnu17, and various aliases for those modes. If no -std option is -specified, clang defaults to gnu11 mode. Many C99 and C11 features are +clang supports the -std option, which changes what language mode clang uses. +The supported modes for C are c89, gnu89, c99, gnu99, c11, gnu11, c17, gnu17, +c2x, gnu2x, and various aliases for those modes. If no -std option is +specified, clang defaults to gnu17 mode. Many C99 and C11 features are supported in earlier modes as a conforming extension, with a warning. Use ``-pedantic-errors`` to request an error if a feature from a later standard revision is used in an earlier mode. @@ -3073,7 +3132,7 @@ Global objects must be constructed before the first kernel using the global obje is executed and destroyed just after the last kernel using the program objects is executed. In OpenCL v2.0 drivers there is no specific API for invoking global constructors. However, an easy workaround would be to enqueue a constructor -initialization kernel that has a name ``@_GLOBAL__sub_I_``. +initialization kernel that has a name ``_GLOBAL__sub_I_``. This kernel is only present if there are any global objects to be initialized in the compiled binary. One way to check this is by passing ``CL_PROGRAM_KERNEL_NAMES`` to ``clGetProgramInfo`` (OpenCL v2.0 s5.8.7). @@ -3089,7 +3148,7 @@ before running any kernels in which the objects are used. clang -cl-std=clc++ test.cl If there are any global objects to be initialized, the final binary will contain -the ``@_GLOBAL__sub_I_test.cl`` kernel to be enqueued. +the ``_GLOBAL__sub_I_test.cl`` kernel to be enqueued. Global destructors can not be invoked in OpenCL v2.0 drivers. However, all memory used for program scope objects is released on ``clReleaseProgram``. @@ -3297,58 +3356,59 @@ Execute ``clang-cl /?`` to see a list of supported options: CL.EXE COMPATIBILITY OPTIONS: /? Display available options /arch: Set architecture for code generation - /Brepro- Write current time into COFF output (default) - /Brepro Do not write current time into COFF output (breaks link.exe /incremental) + /Brepro- Emit an object file which cannot be reproduced over time + /Brepro Emit an object file which can be reproduced over time /clang: Pass to the clang driver - /C Do not discard comments when preprocessing + /C Don't discard comments when preprocessing /c Compile only /d1PP Retain macro definitions in /E mode /d1reportAllClassLayout Dump record layout information - /diagnostics:caret Enable caret and column diagnostics (default) + /diagnostics:caret Enable caret and column diagnostics (on by default) /diagnostics:classic Disable column and caret diagnostics /diagnostics:column Disable caret diagnostics but keep column info /D Define macro - /EH Set exception handling model + /EH Exception handling model /EP Disable linemarker output and preprocess to stdout /execution-charset: - Set runtime encoding, supports only UTF-8 + Runtime encoding, supports only UTF-8 /E Preprocess to stdout /fallback Fall back to cl.exe if clang-cl fails to compile /FA Output assembly code file during compilation - /Fa Set assembly output file name (with /FA) - /Fe Set output executable file name + /Fa Output assembly code to this file during compilation (with /FA) + /Fe Set output executable file or directory (ends in / or \) /FI Include file before parsing /Fi Set preprocess output file name (with /P) - /Fo Set output object file (with /c) + /Fo Set output object file, or directory (ends in / or \) (with /c) /fp:except- /fp:except /fp:fast /fp:precise /fp:strict - /Fp Set pch file name (with /Yc and /Yu) + /Fp Set pch filename (with /Yc and /Yu) /GA Assume thread-local variables are defined in the executable /Gd Set __cdecl as a default calling convention /GF- Disable string pooling /GF Enable string pooling (default) - /GR- Do not emit RTTI data + /GR- Disable emission of RTTI data /Gregcall Set __regcall as a default calling convention - /GR Emit RTTI data (default) + /GR Enable emission of RTTI data /Gr Set __fastcall as a default calling convention /GS- Disable buffer security check /GS Enable buffer security check (default) /Gs Use stack probes (default) /Gs Set stack probe size (default 4096) - /guard: Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks + /guard: Enable Control Flow Guard with /guard:cf, + or only the table with /guard:cf,nochecks /Gv Set __vectorcall as a default calling convention - /Gw- Do not put each data item in its own section (default) + /Gw- Don't put each data item in its own section /Gw Put each data item in its own section - /GX- Deprecated (like not passing /EH) - /GX Deprecated; use /EHsc - /Gy- Do not put each function in its own section (default) + /GX- Disable exception handling + /GX Enable exception handling + /Gy- Don't put each function in its own section (default) /Gy Put each function in its own section /Gz Set __stdcall as a default calling convention /help Display available options - /imsvc Add to system include search path, as if in %INCLUDE% + /imsvc Add directory to system include search path, as if part of %INCLUDE% /I Add directory to include search path /J Make char type unsigned /LDd Create debug DLL @@ -3358,37 +3418,35 @@ Execute ``clang-cl /?`` to see a list of supported options: /MD Use DLL run-time /MTd Use static debug run-time /MT Use static run-time - /O1 Optimize for size (like /Og /Os /Oy /Ob2 /GF /Gy) - /O2 Optimize for speed (like /Og /Oi /Ot /Oy /Ob2 /GF /Gy) + /O0 Disable optimization + /O1 Optimize for size (same as /Og /Os /Oy /Ob2 /GF /Gy) + /O2 Optimize for speed (same as /Og /Oi /Ot /Oy /Ob2 /GF /Gy) /Ob0 Disable function inlining - /Ob1 Only inline functions explicitly or implicitly marked inline + /Ob1 Only inline functions which are (explicitly or implicitly) marked inline /Ob2 Inline functions as deemed beneficial by the compiler /Od Disable optimization /Og No effect /Oi- Disable use of builtin functions /Oi Enable use of builtin functions - /openmp- Disable OpenMP support - /openmp:experimental Enable OpenMP support with experimental SIMD support - /openmp Enable OpenMP support /Os Optimize for size /Ot Optimize for speed - /Ox Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2 + /Ox Deprecated (same as /Og /Oi /Ot /Oy /Ob2); use /O2 instead /Oy- Disable frame pointer omission (x86 only, default) /Oy Enable frame pointer omission (x86 only) /O Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-' - /o Deprecated (set output file name); use /Fe or /Fe + /o Set output file or directory (ends in / or \) /P Preprocess to file /Qvec- Disable the loop vectorization passes /Qvec Enable the loop vectorization passes - /showFilenames- Do not print the name of each compiled file (default) + /showFilenames- Don't print the name of each compiled file (default) /showFilenames Print the name of each compiled file /showIncludes Print info about included files to stderr - /source-charset: Set source encoding, supports only UTF-8 - /std: Set C++ version (c++14,c++17,c++latest) + /source-charset: Source encoding, supports only UTF-8 + /std: Language standard to compile for /TC Treat all source files as C - /Tc Treat as C source file + /Tc Specify a C source file /TP Treat all source files as C++ - /Tp Treat as C++ source file + /Tp Specify a C++ source file /utf-8 Set source and runtime encoding to UTF-8 (default) /U Undefine macro /vd Control vtordisp placement @@ -3405,19 +3463,17 @@ Execute ``clang-cl /?`` to see a list of supported options: /W3 Enable -Wall /W4 Enable -Wall and -Wextra /Wall Enable -Weverything - /WX- Do not treat warnings as errors (default) + /WX- Do not treat warnings as errors /WX Treat warnings as errors /w Disable all warnings - /X Do not add %INCLUDE% to include search path + /X Don't add %INCLUDE% to the include search path /Y- Disable precompiled headers, overrides /Yc and /Yu /Yc Generate a pch file for all code up to and including /Yu Load a pch file and use it instead of all code up to and including /Z7 Enable CodeView debug information in object files - /Zc:alignedNew- Disable C++17 aligned allocation functions - /Zc:alignedNew Enable C++17 aligned allocation functions - /Zc:char8_t- Disable char8_t from c++2a - /Zc:char8_t Enable char8_t from C++2a - /Zc:dllexportInlines- Do not dllexport/dllimport inline member functions of dllexport/import classes + /Zc:char8_t Enable C++2a char8_t type + /Zc:char8_t- Disable C++2a char8_t type + /Zc:dllexportInlines- Don't dllexport/dllimport inline member functions of dllexport/import classes /Zc:dllexportInlines dllexport/dllimport inline member functions of dllexport/import classes (default) /Zc:sizedDealloc- Disable C++14 sized global deallocation functions /Zc:sizedDealloc Enable C++14 sized global deallocation functions @@ -3426,21 +3482,18 @@ Execute ``clang-cl /?`` to see a list of supported options: /Zc:threadSafeInit Enable thread-safe initialization of static variables /Zc:trigraphs- Disable trigraphs (default) /Zc:trigraphs Enable trigraphs - /Zc:twoPhase- Disable two-phase name lookup in templates (default) + /Zc:twoPhase- Disable two-phase name lookup in templates /Zc:twoPhase Enable two-phase name lookup in templates /Zd Emit debug line number tables only - /Zi Like /Z7 - /Zl Do not let object file auto-link default libraries - /Zp Set default maximum struct packing alignment to 1 - /Zp Set default maximum struct packing alignment + /Zi Alias for /Z7. Does not produce PDBs. + /Zl Don't mention any default libraries in the object file + /Zp Set the default maximum struct packing alignment to 1 + /Zp Specify the default maximum struct packing alignment /Zs Syntax-check only OPTIONS: -### Print (but do not run) the commands to run for this compilation --analyze Run the static analyzer - -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang - Trivial automatic variable initialization to zero is only here for benchmarks, it'll - eventually be removed, and I'm OK with that because I'm only using it to benchmark -faddrsig Emit an address-significance table -fansi-escape-codes Use ANSI escape codes for diagnostics -fblocks Enable the 'blocks' language feature @@ -3450,13 +3503,6 @@ Execute ``clang-cl /?`` to see a list of supported options: -fcomplete-member-pointers Require member pointer base types to be complete if they would be significant under the Microsoft ABI -fcoverage-mapping Generate coverage mapping to enable code coverage analysis - -fcs-profile-generate= - Generate instrumented code to collect context sensitive execution counts into - /default.profraw (overridden by LLVM_PROFILE_FILE env var) - -fcs-profile-generate Generate instrumented code to collect context sensitive execution counts into - default.profraw (overridden by LLVM_PROFILE_FILE env var) - -fdebug-compilation-dir - The compilation directory to embed in the debug info. -fdebug-macro Emit macro debug information -fdelayed-template-parsing Parse templated function definitions at the end of the translation unit @@ -3464,17 +3510,16 @@ Execute ``clang-cl /?`` to see a list of supported options: Print absolute paths in diagnostics -fdiagnostics-parseable-fixits Print fix-its in machine parseable form - -fgnuc-version= Sets various macros to claim compatibility with the given GCC version (default is 4.2.1) - -fintegrated-cc1 Run cc1 in-process -flto= Set LTO mode to either 'full' or 'thin' -flto Enable LTO in 'full' mode -fmerge-all-constants Allow merging of constants -fms-compatibility-version= - Dot-separated value representing the Microsoft compiler version number to report in - _MSC_VER (0 = don't define it (default)) + Dot-separated value representing the Microsoft compiler version + number to report in _MSC_VER (0 = don't define it (default)) -fms-compatibility Enable full Microsoft Visual C++ compatibility -fms-extensions Accept some non-standard constructs supported by the Microsoft compiler - -fmsc-version= Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default)) + -fmsc-version= Microsoft compiler version number to report in _MSC_VER + (0 = don't define it (default)) -fno-addrsig Don't emit an address-significance table -fno-builtin- Disable implicit builtin knowledge of a specific function -fno-builtin Disable implicit builtin knowledge of functions @@ -3485,11 +3530,6 @@ Execute ``clang-cl /?`` to see a list of supported options: -fno-debug-macro Do not emit macro debug information -fno-delayed-template-parsing Disable delayed template parsing - -fno-integrated-cc1 Spawn a separate process for each cc1 - -fno-profile-generate Disable generation of profile instrumentation. - -fno-profile-instr-generate - Disable generation of profile instrumentation. - -fno-profile-instr-use Disable using instrumentation data for profile-guided optimization -fno-sanitize-address-poison-custom-array-cookie Disable poisoning array cookies when using custom operator new[] in AddressSanitizer -fno-sanitize-address-use-after-scope @@ -3497,8 +3537,6 @@ Execute ``clang-cl /?`` to see a list of supported options: -fno-sanitize-address-use-odr-indicator Disable ODR indicator globals -fno-sanitize-blacklist Don't use blacklist file for sanitizers - -fno-sanitize-cfi-canonical-jump-tables - Do not make the jump table addresses canonical in the symbol table -fno-sanitize-cfi-cross-dso Disable control flow integrity (CFI) checks for cross-DSO calls. -fno-sanitize-coverage= @@ -3519,26 +3557,17 @@ Execute ``clang-cl /?`` to see a list of supported options: -fno-sanitize-trap= Disable trapping for specified sanitizers -fno-standalone-debug Limit debug information produced to reduce size of debug binary - -fno-temp-file Directly create compilation output files. This may lead to incorrect incremental builds if the compiler crashes -fobjc-runtime= Specify the target Objective-C runtime kind and version - -forder-file-instrumentation - Generate instrumented code to collect order file into default.profraw file - (overridden by '=' form of option or LLVM_PROFILE_FILE env var) -fprofile-exclude-files= Instrument only functions from files where names don't match all the regexes separated by a semi-colon -fprofile-filter-files= Instrument only functions from files where names match any regex separated by a semi-colon - -fprofile-generate= - Generate instrumented code to collect execution counts into - /default.profraw (overridden by LLVM_PROFILE_FILE env var) - -fprofile-generate Generate instrumented code to collect execution counts into - default.profraw (overridden by LLVM_PROFILE_FILE env var) -fprofile-instr-generate= - Generate instrumented code to collect execution counts into - (overridden by LLVM_PROFILE_FILE env var) + Generate instrumented code to collect execution counts into + (overridden by LLVM_PROFILE_FILE env var) -fprofile-instr-generate - Generate instrumented code to collect execution counts into - default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var) + Generate instrumented code to collect execution counts into default.profraw file + (overridden by '=' form of option or LLVM_PROFILE_FILE env var) -fprofile-instr-use= Use instrumentation data for profile-guided optimization -fprofile-remapping-file= @@ -3552,12 +3581,9 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize-address-use-after-scope Enable use-after-scope detection in AddressSanitizer -fsanitize-address-use-odr-indicator - Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized - programs at the cost of an increase in binary size + Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size -fsanitize-blacklist= Path to blacklist file for sanitizers - -fsanitize-cfi-canonical-jump-tables - Make the jump table addresses canonical in the symbol table -fsanitize-cfi-cross-dso Enable control flow integrity (CFI) checks for cross-DSO calls. -fsanitize-cfi-icall-generalize-pointers @@ -3565,8 +3591,7 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize-coverage= Specify the type of coverage instrumentation for Sanitizers -fsanitize-hwaddress-abi= - Select the HWAddressSanitizer ABI to target (interceptor or platform, - default interceptor). This option is currently unused. + Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor) -fsanitize-memory-track-origins= Enable origins tracking in MemorySanitizer -fsanitize-memory-track-origins @@ -3576,8 +3601,6 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize-recover= Enable recovery for specified sanitizers -fsanitize-stats Enable sanitizer statistics gathering. - -fsanitize-system-blacklist= - Path to system blacklist file for sanitizers -fsanitize-thread-atomics Enable atomic operations instrumentation in ThreadSanitizer (default) -fsanitize-thread-func-entry-exit @@ -3587,31 +3610,18 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize-trap= Enable trapping for specified sanitizers -fsanitize-undefined-strip-path-components= Strip (or keep only, if negative) a given number of path components when emitting check metadata. - -fsanitize= Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks + -fsanitize= Turn on runtime checks for various forms of undefined or suspicious + behavior. See user manual for available checks -fsplit-lto-unit Enables splitting of the LTO unit. -fstandalone-debug Emit full debug info for all types used by the program - -fthin-link-bitcode= - Write minimized bitcode to for the ThinLTO thin link only - -fthinlto-index= Perform ThinLTO importing using provided function summary index - -ftime-trace-granularity= - Minimum time granularity (in microseconds) traced by time profiler - -ftime-trace Turn on time profiler. Generates JSON file based on output filename. - -ftrivial-auto-var-init= - Initialize trivial automatic stack variables: uninitialized (default) | pattern - -fvirtual-function-elimination - Enables dead virtual function elimination optimization. Requires -flto=full -fwhole-program-vtables Enables whole-program vtable optimization. Requires -flto -gcodeview-ghash Emit type record hashes in a .debug$H section -gcodeview Generate CodeView debug information - -gdwarf Generate source-level debug information with the default dwarf version -gline-directives-only Emit debug line info directives only -gline-tables-only Emit debug line number tables only - -gno-inline-line-tables Don't emit inline line tables -miamcu Use Intel MCU ABI -mllvm Additional arguments to forward to LLVM's option processing -nobuiltininc Disable builtin #include directories - -print-supported-cpus Print supported cpu models for the given target - (if target is not specified, it will print the supported cpus for the default target) -Qunused-arguments Don't emit warning for unused driver arguments -R Enable the specified remark --target= Generate code for the given target @@ -3717,3 +3727,56 @@ This option is intended to be used as a temporary means to build projects where clang-cl cannot successfully compile all the files. clang-cl may fail to compile a file either because it cannot generate code for some C++ feature, or because it cannot parse some Microsoft language extension. + +Finding Clang runtime libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +clang-cl supports several features that require runtime library support: + +- Address Sanitizer (ASan): ``-fsanitize=address`` +- Undefined Behavior Sanitizer (UBSan): ``-fsanitize=undefined`` +- Code coverage: ``-fprofile-instr-generate -fcoverage-mapping`` +- Profile Guided Optimization (PGO): ``-fprofile-instr-generate`` +- Certain math operations (int128 division) require the builtins library + +In order to use these features, the user must link the right runtime libraries +into their program. These libraries are distributed alongside Clang in the +library resource directory. Clang searches for the resource directory by +searching relative to the Clang executable. For example, if LLVM is installed +in ``C:\Program Files\LLVM``, then the profile runtime library will be located +at the path +``C:\Program Files\LLVM\lib\clang\11.0.0\lib\windows\clang_rt.profile-x86_64.lib``. + +For UBSan, PGO, and coverage, Clang will emit object files that auto-link the +appropriate runtime library, but the user generally needs to help the linker +(whether it is ``lld-link.exe`` or MSVC ``link.exe``) find the library resource +directory. Using the example installation above, this would mean passing +``/LIBPATH:C:\Program Files\LLVM\lib\clang\11.0.0\lib\windows`` to the linker. +If the user links the program with the ``clang`` or ``clang-cl`` drivers, the +driver will pass this flag for them. + +If the linker cannot find the appropriate library, it will emit an error like +this:: + + $ clang-cl -c -fsanitize=undefined t.cpp + + $ lld-link t.obj -dll + lld-link: error: could not open 'clang_rt.ubsan_standalone-x86_64.lib': no such file or directory + lld-link: error: could not open 'clang_rt.ubsan_standalone_cxx-x86_64.lib': no such file or directory + + $ link t.obj -dll -nologo + LINK : fatal error LNK1104: cannot open file 'clang_rt.ubsan_standalone-x86_64.lib' + +To fix the error, add the appropriate ``/libpath:`` flag to the link line. + +For ASan, as of this writing, the user is also responsible for linking against +the correct ASan libraries. + +If the user is using the dynamic CRT (``/MD``), then they should add +``clang_rt.asan_dynamic-x86_64.lib`` to the link line as a regular input. For +other architectures, replace x86_64 with the appropriate name here and below. + +If the user is using the static CRT (``/MT``), then different runtimes are used +to produce DLLs and EXEs. To link a DLL, pass +``clang_rt.asan_dll_thunk-x86_64.lib``. To link an EXE, pass +``-wholearchive:clang_rt.asan-x86_64.lib``. diff --git a/gnu/llvm/clang/docs/analyzer/checkers.rst b/gnu/llvm/clang/docs/analyzer/checkers.rst index dd2365e873f..ca5aec67717 100644 --- a/gnu/llvm/clang/docs/analyzer/checkers.rst +++ b/gnu/llvm/clang/docs/analyzer/checkers.rst @@ -439,7 +439,7 @@ optin.cplusplus.UninitializedObject (C++) This checker reports uninitialized fields in objects created after a constructor call. It doesn't only find direct uninitialized fields, but rather makes a deep inspection of the object, analyzing all of it's fields subfields. -The checker regards inherited fields as direct fields, so one will recieve +The checker regards inherited fields as direct fields, so one will receive warnings for uninitialized inherited data members as well. .. code-block:: cpp @@ -525,7 +525,7 @@ This checker has several options which can be set from command line (e.g. objects that don't have at least one initialized field. Defaults to false. * ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a - warning for each uninitalized field, as opposed to emitting one warning per + warning for each uninitialized field, as opposed to emitting one warning per constructor call, and listing the uninitialized fields that belongs to it in notes. *Defaults to false*. @@ -1374,6 +1374,54 @@ double freed, or use after freed. This check attempts to find such problems. zx_handle_close(sb); } +WebKit +^^^^^^ + +WebKit is an open-source web browser engine available for macOS, iOS and Linux. +This section describes checkers that can find issues in WebKit codebase. + +Most of the checkers focus on memory management for which WebKit uses custom implementation of reference counted smartpointers. + +Checkers are formulated in terms related to ref-counting: + - *Ref-counted type* is either ``Ref`` or ``RefPtr``. + - *Ref-countable type* is any type that implements ``ref()`` and ``deref()`` methods as ``RefPtr<>`` is a template (i. e. relies on duck typing). + - *Uncounted type* is ref-countable but not ref-counted type. + +.. _webkit-RefCntblBaseVirtualDtor: + +webkit.RefCntblBaseVirtualDtor +"""""""""""""""""""""""""""""""""""" +All uncounted types used as base classes must have a virtual destructor. + +Ref-counted types hold their ref-countable data by a raw pointer and allow implicit upcasting from ref-counted pointer to derived type to ref-counted pointer to base type. This might lead to an object of (dynamic) derived type being deleted via pointer to the base class type which C++ standard defines as UB in case the base class doesn't have virtual destructor ``[expr.delete]``. + +.. code-block:: cpp + + struct RefCntblBase { + void ref() {} + void deref() {} + }; + + struct Derived : RefCntblBase { }; // warn + +.. _webkit-NoUncountedMemberChecker: + +webkit.NoUncountedMemberChecker +""""""""""""""""""""""""""""""""""""" +Raw pointers and references to uncounted types can't be used as class members. Only ref-counted types are allowed. + +.. code-block:: cpp + + struct RefCntbl { + void ref() {} + void deref() {} + }; + + struct Foo { + RefCntbl * ptr; // warn + RefCntbl & ptr; // warn + // ... + }; .. _alpha-checkers: @@ -1424,6 +1472,23 @@ Warn about assigning non-{0,1} values to boolean variables. alpha.core ^^^^^^^^^^ +.. _alpha-core-C11Lock: + +alpha.core.C11Lock +"""""""""""""""""" +Similarly to :ref:`alpha.unix.PthreadLock `, checks for +the locking/unlocking of ``mtx_t`` mutexes. + +.. code-block:: cpp + + mtx_t mtx1; + + void bad1(void) + { + mtx_lock(&mtx1); + mtx_lock(&mtx1); // warn: This lock has already been acquired + } + .. _alpha-core-CallAndMessageUnInitRefArg: alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC) @@ -1788,6 +1853,39 @@ Check unreachable code. [x retain]; // warn } +.. _alpha-cplusplus-SmartPtr: + +alpha.cplusplus.SmartPtr (C++) +"""""""""""""""""""""""""""""" +Check for dereference of null smart pointers. + +.. code-block:: cpp + + void deref_smart_ptr() { + std::unique_ptr P; + *P; // warn: dereference of a default constructed smart unique_ptr + } + +alpha.fuchsia +^^^^^^^^^^^^^ + +.. _alpha-fuchsia-lock: + +alpha.fuchsia.Lock +"""""""""""""""""" +Similarly to :ref:`alpha.unix.PthreadLock `, checks for +the locking/unlocking of fuchsia mutexes. + +.. code-block:: cpp + + spin_lock_t mtx1; + + void bad1(void) + { + spin_lock(&mtx1); + spin_lock(&mtx1); // warn: This lock has already been acquired + } + alpha.llvm ^^^^^^^^^^ @@ -1929,6 +2027,38 @@ Warns against using one vs. many plural pattern in code when generating localize alpha.security ^^^^^^^^^^^^^^ + + +alpha.security.cert +^^^^^^^^^^^^^^^^^^^ + +SEI CERT checkers which tries to find errors based on their `C coding rules `_. + +.. _alpha-security-cert-pos-checkers: + +alpha.security.cert.pos +^^^^^^^^^^^^^^^^^^^^^^^ + +SEI CERT checkers of `POSIX C coding rules `_. + +.. _alpha-security-cert-pos-34c: + +alpha.security.cert.pos.34c +""""""""""""""""""""""""""" +Finds calls to the ``putenv`` function which pass a pointer to an automatic variable as the argument. + +.. code-block:: c + + int func(const char *var) { + char env[1024]; + int retval = snprintf(env, sizeof(env),"TEST=%s", var); + if (retval < 0 || (size_t)retval >= sizeof(env)) { + /* Handle error */ + } + + return putenv(env); // putenv function should not be called with auto variables + } + .. _alpha-security-ArrayBound: alpha.security.ArrayBound (C) @@ -2167,9 +2297,9 @@ lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread alpha.unix.SimpleStream (C) """"""""""""""""""""""""""" Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose`` -(demo checker, the subject of the demo (`Slides `_ , +(demo checker, the subject of the demo (`Slides `_ , `Video `_) by Anna Zaks and Jordan Rose presented at the -`2012 LLVM Developers' Meeting `_). +`2012 LLVM Developers' Meeting `_). .. code-block:: c @@ -2297,6 +2427,99 @@ Check for non-determinism caused by sorting of pointers. } +alpha.WebKit +^^^^^^^^^^^^ + +.. _alpha-webkit-UncountedCallArgsChecker: + +alpha.webkit.UncountedCallArgsChecker +""""""""""""""""""""""""""""""""""""" +The goal of this rule is to make sure that lifetime of any dynamically allocated ref-countable object passed as a call argument spans past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. Ref-countable types aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to uncounted types. + +Here are some examples of situations that we warn about as they *might* be potentially unsafe. The logic is that either we're able to guarantee that an argument is safe or it's considered if not a bug then bug-prone. + + .. code-block:: cpp + + RefCountable* provide_uncounted(); + void consume(RefCountable*); + + // In these cases we can't make sure callee won't directly or indirectly call `deref()` on the argument which could make it unsafe from such point until the end of the call. + + void foo1() { + consume(provide_uncounted()); // warn + } + + void foo2() { + RefCountable* uncounted = provide_uncounted(); + consume(uncounted); // warn + } + +Although we are enforcing member variables to be ref-counted by `webkit.NoUncountedMemberChecker` any method of the same class still has unrestricted access to these. Since from a caller's perspective we can't guarantee a particular member won't get modified by callee (directly or indirectly) we don't consider values obtained from members safe. + +Note: It's likely this heuristic could be made more precise with fewer false positives - for example calls to free functions that don't have any parameter other than the pointer should be safe as the callee won't be able to tamper with the member unless it's a global variable. + + .. code-block:: cpp + + struct Foo { + RefPtr member; + void consume(RefCountable*) { /* ... */ } + void bugprone() { + consume(member.get()); // warn + } + }; + +The implementation of this rule is a heuristic - we define a whitelist of kinds of values that are considered safe to be passed as arguments. If we can't prove an argument is safe it's considered an error. + +Allowed kinds of arguments: + +- values obtained from ref-counted objects (including temporaries as those survive the call too) + + .. code-block:: cpp + + RefCountable* provide_uncounted(); + void consume(RefCountable*); + + void foo() { + RefPtr rc = makeRef(provide_uncounted()); + consume(rc.get()); // ok + consume(makeRef(provide_uncounted()).get()); // ok + } + +- forwarding uncounted arguments from caller to callee + + .. code-block:: cpp + + void foo(RefCountable& a) { + bar(a); // ok + } + + Caller of ``foo()`` is responsible for ``a``'s lifetime. + +- ``this`` pointer + + .. code-block:: cpp + + void Foo::foo() { + baz(this); // ok + } + + Caller of ``foo()`` is responsible for keeping the memory pointed to by ``this`` pointer safe. + +- constants + + .. code-block:: cpp + + foo(nullptr, NULL, 0); // ok + +We also define a set of safe transformations which if passed a safe value as an input provide (usually it's the return value) a safe value (or an object that provides safe values). This is also a heuristic. + +- constructors of ref-counted types (including factory methods) +- getters of ref-counted types +- member overloaded operators +- casts +- unary operators like ``&`` or ``*`` + + Debug Checkers --------------- diff --git a/gnu/llvm/clang/docs/analyzer/conf.py b/gnu/llvm/clang/docs/analyzer/conf.py index 09967598acb..6873ecc6c9c 100644 --- a/gnu/llvm/clang/docs/analyzer/conf.py +++ b/gnu/llvm/clang/docs/analyzer/conf.py @@ -49,9 +49,9 @@ copyright = u'2013-%d, Analyzer Team' % date.today().year # built documents. # # The short version. -version = '6' +version = '11' # The full version, including alpha/beta/rc tags. -release = '6' +release = '11' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnu/llvm/clang/docs/analyzer/developer-docs/DebugChecks.rst b/gnu/llvm/clang/docs/analyzer/developer-docs/DebugChecks.rst index 3f9bed78604..48b584a4630 100644 --- a/gnu/llvm/clang/docs/analyzer/developer-docs/DebugChecks.rst +++ b/gnu/llvm/clang/docs/analyzer/developer-docs/DebugChecks.rst @@ -275,6 +275,28 @@ ExprInspection checks See clang_analyzer_denote(). +- ``void clang_analyzer_isTainted(a single argument of any type);`` + + Queries the analyzer whether the expression used as argument is tainted or not. + This is useful in tests, where we don't want to issue warning for all tainted + expressions but only check for certain expressions. + This would help to reduce the *noise* that the `TaintTest` debug checker would + introduce and let you focus on the `expected-warning`'s that you really care + about. + + Example usage:: + + int read_integer() { + int n; + clang_analyzer_isTainted(n); // expected-warning{{NO}} + scanf("%d", &n); + clang_analyzer_isTainted(n); // expected-warning{{YES}} + clang_analyzer_isTainted(n + 2); // expected-warning{{YES}} + clang_analyzer_isTainted(n > 0); // expected-warning{{YES}} + int next_tainted_value = n; // no-warning + return n; + } + Statistics ========== diff --git a/gnu/llvm/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst b/gnu/llvm/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst index 86f972b63e3..0606185f39e 100644 --- a/gnu/llvm/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst +++ b/gnu/llvm/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst @@ -3,14 +3,35 @@ Cross Translation Unit (CTU) Analysis ===================================== Normally, static analysis works in the boundary of one translation unit (TU). -However, with additional steps and configuration we can enable the analysis to inline the definition of a function from another TU. +However, with additional steps and configuration we can enable the analysis to inline the definition of a function from +another TU. .. contents:: :local: -Manual CTU Analysis -------------------- +Overview +________ +CTU analysis can be used in a variety of ways. The importing of external TU definitions can work with pre-dumped PCH +files or generating the necessary AST structure on-demand, during the analysis of the main TU. Driving the static +analysis can also be implemented in multiple ways. The most direct way is to specify the necessary commandline options +of the Clang frontend manually (and generate the prerequisite dependencies of the specific import method by hand). This +process can be automated by other tools, like `CodeChecker `_ and scan-build-py +(preference for the former). + +PCH-based analysis +__________________ +The analysis needs the PCH dumps of all the translations units used in the project. +These can be generated by the Clang Frontend itself, and must be arranged in a specific way in the filesystem. +The index, which maps symbols' USR names to PCH dumps containing them must also be generated by the +`clang-extdef-mapping`. Entries in the index *must* have an `.ast` suffix if the goal +is to use PCH-based analysis, as the lack of that extension signals that the entry is to be used as a source-file, and parsed on-demand. +This tool uses a :doc:`compilation database <../../JSONCompilationDatabase>` to +determine the compilation flags used. +The analysis invocation must be provided with the directory which contains the dumps and the mapping files. + +Manual CTU Analysis +################### Let's consider these source files in our minimal example: .. code-block:: cpp @@ -47,7 +68,8 @@ And a compilation database: ] We'd like to analyze `main.cpp` and discover the division by zero bug. -In order to be able to inline the definition of `foo` from `foo.cpp` first we have to generate the `AST` (or `PCH`) file of `foo.cpp`: +In order to be able to inline the definition of `foo` from `foo.cpp` first we have to generate the `AST` (or `PCH`) file +of `foo.cpp`: .. code-block:: bash @@ -58,7 +80,8 @@ In order to be able to inline the definition of `foo` from `foo.cpp` first we ha compile_commands.json foo.cpp.ast foo.cpp main.cpp $ -The next step is to create a CTU index file which holds the `USR` name and location of external definitions in the source files: +The next step is to create a CTU index file which holds the `USR` name and location of external definitions in the +source files: .. code-block:: bash @@ -85,47 +108,33 @@ We have to feed Clang with CTU specific extra arguments: $ pwd /path/to/your/project - $ clang++ --analyze -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang ctu-dir=. -Xclang -analyzer-output=plist-multi-file main.cpp + $ clang++ --analyze \ + -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true \ + -Xclang -analyzer-config -Xclang ctu-dir=. \ + -Xclang -analyzer-output=plist-multi-file \ + main.cpp main.cpp:5:12: warning: Division by zero return 3 / foo(); ~~^~~~~~~ 1 warning generated. $ # The plist file with the result is generated. - $ ls + $ ls -F compile_commands.json externalDefMap.txt foo.ast foo.cpp foo.cpp.ast main.cpp main.plist $ -This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use `CodeChecker` or `scan-build-py`. +This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use +`CodeChecker` or `scan-build-py`. Automated CTU Analysis with CodeChecker ---------------------------------------- +####################################### The `CodeChecker `_ project fully supports automated CTU analysis with Clang. Once we have set up the `PATH` environment variable and we activated the python `venv` then it is all it takes: .. code-block:: bash $ CodeChecker analyze --ctu compile_commands.json -o reports - [INFO 2019-07-16 17:21] - Pre-analysis started. - [INFO 2019-07-16 17:21] - Collecting data for ctu analysis. - [INFO 2019-07-16 17:21] - [1/2] foo.cpp - [INFO 2019-07-16 17:21] - [2/2] main.cpp - [INFO 2019-07-16 17:21] - Pre-analysis finished. - [INFO 2019-07-16 17:21] - Starting static analysis ... - [INFO 2019-07-16 17:21] - [1/2] clangsa analyzed foo.cpp successfully. - [INFO 2019-07-16 17:21] - [2/2] clangsa analyzed main.cpp successfully. - [INFO 2019-07-16 17:21] - ----==== Summary ====---- - [INFO 2019-07-16 17:21] - Successfully analyzed - [INFO 2019-07-16 17:21] - clangsa: 2 - [INFO 2019-07-16 17:21] - Total analyzed compilation commands: 2 - [INFO 2019-07-16 17:21] - ----=================---- - [INFO 2019-07-16 17:21] - Analysis finished. - [INFO 2019-07-16 17:21] - To view results in the terminal use the "CodeChecker parse" command. - [INFO 2019-07-16 17:21] - To store results use the "CodeChecker store" command. - [INFO 2019-07-16 17:21] - See --help and the user guide for further options about parsing and storing the reports. - [INFO 2019-07-16 17:21] - ----=================---- - [INFO 2019-07-16 17:21] - Analysis length: 0.659618854523 sec. - $ ls - compile_commands.json foo.cpp foo.cpp.ast main.cpp reports + $ ls -F + compile_commands.json foo.cpp foo.cpp.ast main.cpp reports/ $ tree reports reports ├── compile_cmd.json @@ -174,9 +183,9 @@ Or we can use `CodeChecker parse -e html` to export the results into HTML format $ firefox html_out/index.html Automated CTU Analysis with scan-build-py (don't do it) -------------------------------------------------------- -We actively develop CTU with CodeChecker as a "runner" script, `scan-build-py` is not actively developed for CTU. -`scan-build-py` has various errors and issues, expect it to work with the very basic projects only. +############################################################# +We actively develop CTU with CodeChecker as the driver for this feature, `scan-build-py` is not actively developed for CTU. +`scan-build-py` has various errors and issues, expect it to work only with the very basic projects only. Example usage of scan-build-py: @@ -191,3 +200,178 @@ Example usage of scan-build-py: Opening in existing browser session. ^C $ + +.. _ctu-on-demand: + +On-demand analysis +__________________ +The analysis produces the necessary AST structure of external TUs during analysis. This requires the +exact compiler invocations for each TU, which can be generated by hand, or by tools driving the analyzer. +The compiler invocation is a shell command that could be used to compile the TU-s main source file. +The mapping from absolute source file paths of a TU to lists of compilation command segments used to +compile said TU are given in YAML format referred to as `invocation list`, and must be passed as an +analyer-config argument. +The index, which maps function USR names to source files containing them must also be generated by the +`clang-extdef-mapping`. Entries in the index must *not* have an `.ast` suffix if the goal +is to use On-demand analysis, as that extension signals that the entry is to be used as an PCH-dump. +The mapping of external definitions implicitly uses a +:doc:`compilation database <../../JSONCompilationDatabase>` to determine the compilation flags used. +The analysis invocation must be provided with the directory which contains the mapping +files, and the `invocation list` which is used to determine compiler flags. + + +Manual CTU Analysis +################### + +Let's consider these source files in our minimal example: + +.. code-block:: cpp + + // main.cpp + int foo(); + + int main() { + return 3 / foo(); + } + +.. code-block:: cpp + + // foo.cpp + int foo() { + return 0; + } + +The compilation database: + +.. code-block:: bash + + [ + { + "directory": "/path/to/your/project", + "command": "clang++ -c foo.cpp -o foo.o", + "file": "foo.cpp" + }, + { + "directory": "/path/to/your/project", + "command": "clang++ -c main.cpp -o main.o", + "file": "main.cpp" + } + ] + +The `invocation list`: + +.. code-block:: bash + + "/path/to/your/project/foo.cpp": + - "clang++" + - "-c" + - "/path/to/your/project/foo.cpp" + - "-o" + - "/path/to/your/project/foo.o" + + "/path/to/your/project/main.cpp": + - "clang++" + - "-c" + - "/path/to/your/project/main.cpp" + - "-o" + - "/path/to/your/project/main.o" + +We'd like to analyze `main.cpp` and discover the division by zero bug. +As we are using On-demand mode, we only need to create a CTU index file which holds the `USR` name and location of +external definitions in the source files: + +.. code-block:: bash + + $ clang-extdef-mapping -p . foo.cpp + c:@F@foo# /path/to/your/project/foo.cpp + $ clang-extdef-mapping -p . foo.cpp > externalDefMap.txt + +Now everything is available for the CTU analysis. +We have to feed Clang with CTU specific extra arguments: + +.. code-block:: bash + + $ pwd + /path/to/your/project + $ clang++ --analyze \ + -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true \ + -Xclang -analyzer-config -Xclang ctu-dir=. \ + -Xclang -analyzer-config -Xclang ctu-invocation-list=invocations.yaml \ + -Xclang -analyzer-output=plist-multi-file \ + main.cpp + main.cpp:5:12: warning: Division by zero + return 3 / foo(); + ~~^~~~~~~ + 1 warning generated. + $ # The plist file with the result is generated. + $ ls -F + compile_commands.json externalDefMap.txt foo.cpp main.cpp main.plist + $ + +This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use +`CodeChecker` or `scan-build-py`. + +Automated CTU Analysis with CodeChecker +####################################### +The `CodeChecker `_ project fully supports automated CTU analysis with Clang. +Once we have set up the `PATH` environment variable and we activated the python `venv` then it is all it takes: + +.. code-block:: bash + + $ CodeChecker analyze --ctu --ctu-ast-loading-mode on-demand compile_commands.json -o reports + $ ls -F + compile_commands.json foo.cpp main.cpp reports/ + $ tree reports + reports + ├── compile_cmd.json + ├── compiler_info.json + ├── foo.cpp_53f6fbf7ab7ec9931301524b551959e2.plist + ├── main.cpp_23db3d8df52ff0812e6e5a03071c8337.plist + ├── metadata.json + └── unique_compile_commands.json + + 0 directories, 6 files + $ + +The `plist` files contain the results of the analysis, which may be viewed with the regular analysis tools. +E.g. one may use `CodeChecker parse` to view the results in command line: + +.. code-block:: bash + + $ CodeChecker parse reports + [HIGH] /home/egbomrt/ctu_mini_raw_project/main.cpp:5:12: Division by zero [core.DivideZero] + return 3 / foo(); + ^ + + Found 1 defect(s) in main.cpp + + + ----==== Summary ====---- + ----------------------- + Filename | Report count + ----------------------- + main.cpp | 1 + ----------------------- + ----------------------- + Severity | Report count + ----------------------- + HIGH | 1 + ----------------------- + ----=================---- + Total number of reports: 1 + ----=================---- + +Or we can use `CodeChecker parse -e html` to export the results into HTML format: + +.. code-block:: bash + + $ CodeChecker parse -e html -o html_out reports + $ firefox html_out/index.html + +Automated CTU Analysis with scan-build-py (don't do it) +####################################################### +We actively develop CTU with CodeChecker as the driver for feature, `scan-build-py` is not actively developed for CTU. +`scan-build-py` has various errors and issues, expect it to work only with the very basic projects only. + +Currently On-demand analysis is not supported with `scan-build-py`. + diff --git a/gnu/llvm/clang/docs/conf.py b/gnu/llvm/clang/docs/conf.py index e16ff49eb28..164f15d1e28 100644 --- a/gnu/llvm/clang/docs/conf.py +++ b/gnu/llvm/clang/docs/conf.py @@ -50,9 +50,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year # built documents. # # The short version. -version = '10' +version = '11' # The full version, including alpha/beta/rc tags. -release = '10' +release = '11' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnu/llvm/clang/docs/index.rst b/gnu/llvm/clang/docs/index.rst index 493f736f2be..c49312861ba 100644 --- a/gnu/llvm/clang/docs/index.rst +++ b/gnu/llvm/clang/docs/index.rst @@ -77,6 +77,7 @@ Using Clang Tools ClangCheck ClangFormat ClangFormatStyleOptions + ClangFormattedStatus Design Documents ================ diff --git a/gnu/llvm/clang/docs/tools/dump_ast_matchers.py b/gnu/llvm/clang/docs/tools/dump_ast_matchers.py index c96c1ca27ac..045833be767 100755 --- a/gnu/llvm/clang/docs/tools/dump_ast_matchers.py +++ b/gnu/llvm/clang/docs/tools/dump_ast_matchers.py @@ -101,8 +101,15 @@ def unify_arguments(args): args = re.sub(r'extern const\s+(.*)&', r'\1 ', args) args = re.sub(r'&', r' ', args) args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args) + args = re.sub(r'BindableMatcher', r'Matcher', args) + args = re.sub(r'const Matcher', r'Matcher', args) return args +def unify_type(result_type): + """Gets rid of anything the user doesn't care about in the type name.""" + result_type = re.sub(r'^internal::(Bindable)?Matcher<([a-zA-Z_][a-zA-Z0-9_]*)>$', r'\2', result_type) + return result_type + def add_matcher(result_type, name, args, comment, is_dyncast=False): """Adds a matcher to one of our categories.""" if name == 'id': @@ -111,6 +118,7 @@ def add_matcher(result_type, name, args, comment, is_dyncast=False): matcher_id = '%s%d' % (name, ids[name]) ids[name] += 1 args = unify_arguments(args) + result_type = unify_type(result_type) matcher_html = TD_TEMPLATE % { 'result': esc('Matcher<%s>' % result_type), 'name': name, @@ -119,7 +127,8 @@ def add_matcher(result_type, name, args, comment, is_dyncast=False): 'id': matcher_id, } if is_dyncast: - node_matchers[result_type + name] = matcher_html + dict = node_matchers + lookup = result_type + name # Use a heuristic to figure out whether a matcher is a narrowing or # traversal matcher. By default, matchers that take other matchers as # arguments (and are not node matchers) do traversal. We specifically @@ -127,9 +136,14 @@ def add_matcher(result_type, name, args, comment, is_dyncast=False): # arguments. elif ('Matcher<' not in args or name in ['allOf', 'anyOf', 'anything', 'unless']): - narrowing_matchers[result_type + name + esc(args)] = matcher_html + dict = narrowing_matchers + lookup = result_type + name + esc(args) else: - traversal_matchers[result_type + name + esc(args)] = matcher_html + dict = traversal_matchers + lookup = result_type + name + esc(args) + + if dict.get(lookup) is None or len(dict.get(lookup)) < len(matcher_html): + dict[lookup] = matcher_html def act_on_decl(declaration, comment, allowed_types): """Parse the matcher out of the given declaration and comment. @@ -139,6 +153,9 @@ def act_on_decl(declaration, comment, allowed_types): definition. """ if declaration.strip(): + + if re.match(r'^\s?(#|namespace|using)', declaration): return + # Node matchers are defined by writing: # VariadicDynCastAllOfMatcher name; m = re.match(r""".*Variadic(?:DynCast)?AllOfMatcher\s*< @@ -213,6 +230,28 @@ def act_on_decl(declaration, comment, allowed_types): add_matcher(result_type, name, args, comment) return + m = re.match(r"""^\s*AST_POLYMORPHIC_MATCHER_REGEX(?:_OVERLOAD)?\( + \s*([^\s,]+)\s*, + \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\), + \s*([^\s,]+)\s* + (?:,\s*\d+\s*)? + \)\s*{\s*$""", declaration, flags=re.X) + + if m: + name, results, arg_name = m.groups()[0:3] + result_types = [r.strip() for r in results.split(',')] + if allowed_types and allowed_types != result_types: + raise Exception('Inconsistent documentation for: %s' % name) + arg = "StringRef %s, Regex::RegexFlags Flags = NoFlags" % arg_name + comment += """ +If the matcher is used in clang-query, RegexFlags parameter +should be passed as a quoted string. e.g: "NoFlags". +Flags can be combined with '|' example \"IgnoreCase | BasicRegex\" +""" + for result_type in result_types: + add_matcher(result_type, name, arg, comment) + return + m = re.match(r"""^\s*AST_MATCHER_FUNCTION(_P)?(.?)(?:_OVERLOAD)?\( (?:\s*([^\s,]+)\s*,)? \s*([^\s,]+)\s* @@ -258,6 +297,31 @@ def act_on_decl(declaration, comment, allowed_types): add_matcher(result_type, name, args, comment) return + m = re.match(r"""^\s*AST_MATCHER_REGEX(?:_OVERLOAD)?\( + \s*([^\s,]+)\s*, + \s*([^\s,]+)\s*, + \s*([^\s,]+)\s* + (?:,\s*\d+\s*)? + \)\s*{""", declaration, flags=re.X) + if m: + result, name, arg_name = m.groups()[0:3] + if not result: + if not allowed_types: + raise Exception('Did not find allowed result types for: %s' % name) + result_types = allowed_types + else: + result_types = [result] + arg = "StringRef %s, Regex::RegexFlags Flags = NoFlags" % arg_name + comment += """ +If the matcher is used in clang-query, RegexFlags parameter +should be passed as a quoted string. e.g: "NoFlags". +Flags can be combined with '|' example \"IgnoreCase | BasicRegex\" +""" + + for result_type in result_types: + add_matcher(result_type, name, arg, comment) + return + # Parse ArgumentAdapting matchers. m = re.match( r"""^.*ArgumentAdaptingMatcherFunc<.*>\s* @@ -278,6 +342,22 @@ def act_on_decl(declaration, comment, allowed_types): add_matcher(result, name, '%s, ..., %s' % (arg, arg), comment) return + m = re.match( + r"""^.*internal::VariadicFunction\s*<\s* + internal::PolymorphicMatcherWithParam1<[\S\s]+ + AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)>,\s*([^,]+), + \s*[^>]+>\s*([a-zA-Z]*);$""", + declaration, flags=re.X) + + if m: + results, arg, name = m.groups()[:3] + + result_types = [r.strip() for r in results.split(',')] + for result_type in result_types: + add_matcher(result_type, name, '%s, ..., %s' % (arg, arg), comment) + return + + # Parse Variadic operator matchers. m = re.match( r"""^.*VariadicOperatorMatcherFunc\s*<\s*([^,]+),\s*([^\s]+)\s*>\s* @@ -295,16 +375,27 @@ def act_on_decl(declaration, comment, allowed_types): # Parse free standing matcher functions, like: # Matcher Name(Matcher InnerMatcher) { - m = re.match(r"""^\s*(.*)\s+ + m = re.match(r"""^\s*(?:template\s+<\s*(?:class|typename)\s+(.+)\s*>\s+)? + (.*)\s+ ([^\s\(]+)\s*\( (.*) \)\s*{""", declaration, re.X) if m: - result, name, args = m.groups() + template_name, result, name, args = m.groups() + if template_name: + matcherTemplateArgs = re.findall(r'Matcher<\s*(%s)\s*>' % template_name, args) + templateArgs = re.findall(r'(?:^|[\s,<])(%s)(?:$|[\s,>])' % template_name, args) + if len(matcherTemplateArgs) < len(templateArgs): + # The template name is used naked, so don't replace with `*`` later on + template_name = None + else : + args = re.sub(r'(^|[\s,<])%s($|[\s,>])' % template_name, r'\1*\2', args) args = ', '.join(p.strip() for p in args.split(',')) - m = re.match(r'.*\s+internal::(Bindable)?Matcher<([^>]+)>$', result) + m = re.match(r'(?:^|.*\s+)internal::(?:Bindable)?Matcher<([^>]+)>$', result) if m: - result_types = [m.group(2)] + result_types = [m.group(1)] + if template_name and len(result_types) is 1 and result_types[0] == template_name: + result_types = ['*'] else: result_types = extract_result_types(comment) if not result_types: diff --git a/gnu/llvm/clang/docs/tools/dump_format_style.py b/gnu/llvm/clang/docs/tools/dump_format_style.py index acb0dfcaf4a..61167979b3e 100755 --- a/gnu/llvm/clang/docs/tools/dump_format_style.py +++ b/gnu/llvm/clang/docs/tools/dump_format_style.py @@ -225,4 +225,4 @@ contents = open(DOC_FILE).read() contents = substitute(contents, 'FORMAT_STYLE_OPTIONS', options_text) with open(DOC_FILE, 'wb') as output: - output.write(contents) + output.write(contents.encode()) diff --git a/gnu/llvm/clang/docs/tools/generate_formatted_state.py b/gnu/llvm/clang/docs/tools/generate_formatted_state.py new file mode 100755 index 00000000000..41d5cd9d400 --- /dev/null +++ b/gnu/llvm/clang/docs/tools/generate_formatted_state.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# A tool to parse creates a document outlining how clang formatted the +# LLVM project is. + +import sys +import os +import subprocess +from datetime import datetime + + +def get_git_revision_short_hash(): + return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'] + ).decode(sys.stdout.encoding).strip() + + +def get_style(count, passed): + if passed == count: + return ":good:" + elif passed != 0: + return ":part:" + else: + return ":none:" + + +TOP_DIR = os.path.join(os.path.dirname(__file__), '../../..') +CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..') +DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormattedStatus.rst') + +rootdir = TOP_DIR + +skipped_dirs = [".git", "test"] +suffixes = (".cpp", ".h") + +rst_prefix = """\ +.. raw:: html + + + +.. role:: none +.. role:: part +.. role:: good +.. role:: total + +====================== +Clang Formatted Status +====================== + +:doc:`ClangFormattedStatus` describes the state of LLVM source +tree in terms of conformance to :doc:`ClangFormat` as of: {today} (`{sha} `_). + + +.. list-table:: LLVM Clang-Format Status + :widths: 50 25 25 25 25 + :header-rows: 1\n + * - Directory + - Total Files + - Formatted Files + - Unformatted Files + - % Complete +""" + +table_row = """\ + * - {path} + - {style}`{count}` + - {style}`{passes}` + - {style}`{fails}` + - {style2}`{percent}%` +""" + +FNULL = open(os.devnull, 'w') + +with open(DOC_FILE, 'wb') as output: + sha = get_git_revision_short_hash() + today = datetime.now().strftime("%B %d, %Y %H:%M:%S") + output.write(bytes(rst_prefix.format(today=today, + sha=sha).encode("utf-8"))) + + total_files_count = 0 + total_files_pass = 0 + total_files_fail = 0 + for root, subdirs, files in os.walk(rootdir): + for subdir in subdirs: + if any(sd == subdir for sd in skipped_dirs): + subdirs.remove(subdir) + else: + act_sub_dir = os.path.join(root, subdir) + # Check the git index to see if the directory contains tracked + # files. Reditect the output to a null descriptor as we aren't + # interested in it, just the return code. + git_check = subprocess.Popen( + ["git", "ls-files", "--error-unmatch", act_sub_dir], + stdout=FNULL, + stderr=FNULL) + if git_check.wait() != 0: + print("Skipping directory: ", act_sub_dir) + subdirs.remove(subdir) + + path = os.path.relpath(root, TOP_DIR) + path = path.replace('\\', '/') + + file_count = 0 + file_pass = 0 + file_fail = 0 + for filename in files: + file_path = os.path.join(root, filename) + ext = os.path.splitext(file_path)[-1].lower() + if not ext.endswith(suffixes): + continue + + file_count += 1 + + args = ["clang-format", "-n", file_path] + cmd = subprocess.Popen(args, stderr=subprocess.PIPE) + stdout, err = cmd.communicate() + + relpath = os.path.relpath(file_path, TOP_DIR) + relpath = relpath.replace('\\', '/') + if err.decode(sys.stdout.encoding).find(': warning:') > 0: + print(relpath, ":", "FAIL") + file_fail += 1 + else: + print(relpath, ":", "PASS") + file_pass += 1 + + total_files_count += file_count + total_files_pass += file_pass + total_files_fail += file_fail + + if file_count > 0: + percent = (int(100.0 * (float(file_pass)/float(file_count)))) + style = get_style(file_count, file_pass) + output.write(bytes(table_row.format(path=path, + count=file_count, + passes=file_pass, + fails=file_fail, + percent=str(percent), style="", + style2=style).encode("utf-8"))) + output.flush() + + print("----\n") + print(path, file_count, file_pass, file_fail, percent) + print("----\n") + + total_percent = (float(total_files_pass)/float(total_files_count)) + percent_str = str(int(100.0 * total_percent)) + output.write(bytes(table_row.format(path="Total", + count=total_files_count, + passes=total_files_pass, + fails=total_files_fail, + percent=percent_str, style=":total:", + style2=":total:").encode("utf-8"))) diff --git a/gnu/llvm/clang/examples/Attribute/Attribute.cpp b/gnu/llvm/clang/examples/Attribute/Attribute.cpp new file mode 100644 index 00000000000..998f175dae5 --- /dev/null +++ b/gnu/llvm/clang/examples/Attribute/Attribute.cpp @@ -0,0 +1,81 @@ +//===- Attribute.cpp ------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Example clang plugin which adds an an annotation to file-scope declarations +// with the 'example' attribute. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/Sema/ParsedAttr.h" +#include "clang/Sema/Sema.h" +#include "clang/Sema/SemaDiagnostic.h" +#include "llvm/IR/Attributes.h" +using namespace clang; + +namespace { + +struct ExampleAttrInfo : public ParsedAttrInfo { + ExampleAttrInfo() { + // Can take an optional string argument (the check that the argument + // actually is a string happens in handleDeclAttribute). + OptArgs = 1; + // GNU-style __attribute__(("example")) and C++-style [[example]] and + // [[plugin::example]] supported. + static constexpr Spelling S[] = {{ParsedAttr::AS_GNU, "example"}, + {ParsedAttr::AS_CXX11, "example"}, + {ParsedAttr::AS_CXX11, "plugin::example"}}; + Spellings = S; + } + + bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, + const Decl *D) const override { + // This attribute appertains to functions only. + if (!isa(D)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << "functions"; + return false; + } + return true; + } + + AttrHandling handleDeclAttribute(Sema &S, Decl *D, + const ParsedAttr &Attr) const override { + // Check if the decl is at file scope. + if (!D->getDeclContext()->isFileContext()) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only allowed at file scope"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; + } + // Check if we have an optional string argument. + StringRef Str = ""; + if (Attr.getNumArgs() > 0) { + Expr *ArgExpr = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(ArgExpr->IgnoreParenCasts()); + if (Literal) { + Str = Literal->getString(); + } else { + S.Diag(ArgExpr->getExprLoc(), diag::err_attribute_argument_type) + << Attr.getAttrName() << AANT_ArgumentString; + return AttributeNotApplied; + } + } + // Attach an annotate attribute to the Decl. + D->addAttr(AnnotateAttr::Create(S.Context, "example(" + Str.str() + ")", + Attr.getRange())); + return AttributeApplied; + } +}; + +} // namespace + +static ParsedAttrInfoRegistry::Add X("example", ""); diff --git a/gnu/llvm/clang/examples/Attribute/CMakeLists.txt b/gnu/llvm/clang/examples/Attribute/CMakeLists.txt new file mode 100644 index 00000000000..42f04f5039b --- /dev/null +++ b/gnu/llvm/clang/examples/Attribute/CMakeLists.txt @@ -0,0 +1,11 @@ +add_llvm_library(Attribute MODULE Attribute.cpp PLUGIN_TOOL clang) + +if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) + target_link_libraries(Attribute PRIVATE + clangAST + clangBasic + clangFrontend + clangLex + LLVMSupport + ) +endif() diff --git a/gnu/llvm/clang/examples/CMakeLists.txt b/gnu/llvm/clang/examples/CMakeLists.txt index e4fedf3682e..c014b3ddfe9 100644 --- a/gnu/llvm/clang/examples/CMakeLists.txt +++ b/gnu/llvm/clang/examples/CMakeLists.txt @@ -6,3 +6,4 @@ endif() add_subdirectory(clang-interpreter) add_subdirectory(PrintFunctionNames) add_subdirectory(AnnotateFunctions) +add_subdirectory(Attribute) diff --git a/gnu/llvm/clang/examples/clang-interpreter/main.cpp b/gnu/llvm/clang/examples/clang-interpreter/main.cpp index c0aae472230..6b4cdca15fb 100644 --- a/gnu/llvm/clang/examples/clang-interpreter/main.cpp +++ b/gnu/llvm/clang/examples/clang-interpreter/main.cpp @@ -54,7 +54,7 @@ private: std::unique_ptr TM; const DataLayout DL; MangleAndInterner Mangle{ES, DL}; - JITDylib &MainJD{ES.createJITDylib("
")}; + JITDylib &MainJD{ES.createBareJITDylib("
")}; RTDyldObjectLinkingLayer ObjectLayer{ES, createMemMgr}; IRCompileLayer CompileLayer{ES, ObjectLayer, std::make_unique(*TM)}; diff --git a/gnu/llvm/clang/include/clang-c/BuildSystem.h b/gnu/llvm/clang/include/clang-c/BuildSystem.h index 4e9f6dee027..296e61247ce 100644 --- a/gnu/llvm/clang/include/clang-c/BuildSystem.h +++ b/gnu/llvm/clang/include/clang-c/BuildSystem.h @@ -117,7 +117,7 @@ clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor, const char *name); /** - * Sets the umbrealla header name that the module.map describes. + * Sets the umbrella header name that the module.map describes. * \returns 0 for success, non-zero to indicate an error. */ CINDEX_LINKAGE enum CXErrorCode diff --git a/gnu/llvm/clang/include/clang-c/Index.h b/gnu/llvm/clang/include/clang-c/Index.h index b653995ebbd..9f5a727c84b 100644 --- a/gnu/llvm/clang/include/clang-c/Index.h +++ b/gnu/llvm/clang/include/clang-c/Index.h @@ -33,24 +33,19 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 59 +#define CINDEX_VERSION_MINOR 61 -#define CINDEX_VERSION_ENCODE(major, minor) ( \ - ((major) * 10000) \ - + ((minor) * 1)) +#define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1)) -#define CINDEX_VERSION CINDEX_VERSION_ENCODE( \ - CINDEX_VERSION_MAJOR, \ - CINDEX_VERSION_MINOR ) +#define CINDEX_VERSION \ + CINDEX_VERSION_ENCODE(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR) -#define CINDEX_VERSION_STRINGIZE_(major, minor) \ - #major"."#minor -#define CINDEX_VERSION_STRINGIZE(major, minor) \ - CINDEX_VERSION_STRINGIZE_(major, minor) +#define CINDEX_VERSION_STRINGIZE_(major, minor) #major "." #minor +#define CINDEX_VERSION_STRINGIZE(major, minor) \ + CINDEX_VERSION_STRINGIZE_(major, minor) -#define CINDEX_VERSION_STRING CINDEX_VERSION_STRINGIZE( \ - CINDEX_VERSION_MAJOR, \ - CINDEX_VERSION_MINOR) +#define CINDEX_VERSION_STRING \ + CINDEX_VERSION_STRINGIZE(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR) LLVM_CLANG_C_EXTERN_C_BEGIN @@ -382,7 +377,7 @@ typedef struct { * \param outID stores the returned CXFileUniqueID. * \returns If there was a failure getting the unique ID, returns non-zero, * otherwise returns 0. -*/ + */ CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID); /** @@ -390,8 +385,8 @@ CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID); * multiple inclusions, either with the conventional * \#ifndef/\#define/\#endif macro guards or with \#pragma once. */ -CINDEX_LINKAGE unsigned -clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file); +CINDEX_LINKAGE unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, + CXFile file); /** * Retrieve a file handle within the given translation unit. @@ -496,8 +491,7 @@ CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1, * in a particular translation unit. */ CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu, - CXFile file, - unsigned line, + CXFile file, unsigned line, unsigned column); /** * Retrieves the source location associated with a given character offset @@ -566,8 +560,7 @@ CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range); * buffer to which the given source location points. */ CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -613,8 +606,7 @@ CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location, */ CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location, CXString *filename, - unsigned *line, - unsigned *column); + unsigned *line, unsigned *column); /** * Legacy API to retrieve the file, line, column, and offset represented @@ -625,8 +617,7 @@ CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location, * details. */ CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -653,8 +644,7 @@ CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, * buffer to which the given source location points. */ CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -682,10 +672,8 @@ CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location, * buffer to which the given source location points. */ CINDEX_LINKAGE void clang_getFileLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, - unsigned *column, - unsigned *offset); + CXFile *file, unsigned *line, + unsigned *column, unsigned *offset); /** * Retrieve a source location representing the first character within a @@ -727,7 +715,8 @@ CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu, * The preprocessor will skip lines when they are surrounded by an * if/ifdef/ifndef directive whose condition does not evaluate to true. */ -CINDEX_LINKAGE CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit tu); +CINDEX_LINKAGE CXSourceRangeList * +clang_getAllSkippedRanges(CXTranslationUnit tu); /** * Destroy the given \c CXSourceRangeList. @@ -758,7 +747,7 @@ enum CXDiagnosticSeverity { * This diagnostic is a note that should be attached to the * previous (non-note) diagnostic. */ - CXDiagnostic_Note = 1, + CXDiagnostic_Note = 1, /** * This diagnostic indicates suspicious code that may not be @@ -769,14 +758,14 @@ enum CXDiagnosticSeverity { /** * This diagnostic indicates that the code is ill-formed. */ - CXDiagnostic_Error = 3, + CXDiagnostic_Error = 3, /** * This diagnostic indicates that the code is ill-formed such * that future parser recovery is unlikely to produce useful * results. */ - CXDiagnostic_Fatal = 4 + CXDiagnostic_Fatal = 4 }; /** @@ -849,9 +838,8 @@ enum CXLoadDiag_Error { * \returns A loaded CXDiagnosticSet if successful, and NULL otherwise. These * diagnostics should be released using clang_disposeDiagnosticSet(). */ -CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file, - enum CXLoadDiag_Error *error, - CXString *errorString); +CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics( + const char *file, enum CXLoadDiag_Error *error, CXString *errorString); /** * Release a CXDiagnosticSet and all of its contained diagnostics. @@ -891,7 +879,7 @@ CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, * \param Unit the translation unit to query. */ CINDEX_LINKAGE CXDiagnosticSet - clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); +clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); /** * Destroy a diagnostic. @@ -997,7 +985,7 @@ CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void); * Determine the severity of the given diagnostic. */ CINDEX_LINKAGE enum CXDiagnosticSeverity -clang_getDiagnosticSeverity(CXDiagnostic); + clang_getDiagnosticSeverity(CXDiagnostic); /** * Retrieve the source location of the given diagnostic. @@ -1049,8 +1037,8 @@ CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic); * * \returns The name of the given diagnostic category. */ -CINDEX_DEPRECATED CINDEX_LINKAGE -CXString clang_getDiagnosticCategoryName(unsigned Category); +CINDEX_DEPRECATED CINDEX_LINKAGE CXString +clang_getDiagnosticCategoryName(unsigned Category); /** * Retrieve the diagnostic category text for a given diagnostic. @@ -1112,9 +1100,8 @@ CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic); * \returns A string containing text that should be replace the source * code indicated by the \c ReplacementRange. */ -CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, - unsigned FixIt, - CXSourceRange *ReplacementRange); +CINDEX_LINKAGE CXString clang_getDiagnosticFixIt( + CXDiagnostic Diagnostic, unsigned FixIt, CXSourceRange *ReplacementRange); /** * @} @@ -1177,12 +1164,9 @@ clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); * guarantee their validity until the call to this function returns. */ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile( - CXIndex CIdx, - const char *source_filename, - int num_clang_command_line_args, - const char * const *clang_command_line_args, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files); + CXIndex CIdx, const char *source_filename, int num_clang_command_line_args, + const char *const *clang_command_line_args, unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files); /** * Same as \c clang_createTranslationUnit2, but returns @@ -1190,9 +1174,8 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile( * routine returns a \c NULL \c CXTranslationUnit, without further detailed * error codes. */ -CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit( - CXIndex CIdx, - const char *ast_filename); +CINDEX_LINKAGE CXTranslationUnit +clang_createTranslationUnit(CXIndex CIdx, const char *ast_filename); /** * Create a translation unit from an AST file (\c -emit-ast). @@ -1202,10 +1185,9 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit( * * \returns Zero on success, otherwise returns an error code. */ -CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2( - CXIndex CIdx, - const char *ast_filename, - CXTranslationUnit *out_TU); +CINDEX_LINKAGE enum CXErrorCode +clang_createTranslationUnit2(CXIndex CIdx, const char *ast_filename, + CXTranslationUnit *out_TU); /** * Flags that control the creation of translation units. @@ -1383,14 +1365,11 @@ CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void); * routine returns a \c NULL \c CXTranslationUnit, without further detailed * error codes. */ -CINDEX_LINKAGE CXTranslationUnit -clang_parseTranslationUnit(CXIndex CIdx, - const char *source_filename, - const char *const *command_line_args, - int num_command_line_args, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options); +CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit( + CXIndex CIdx, const char *source_filename, + const char *const *command_line_args, int num_command_line_args, + struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, + unsigned options); /** * Parse the given source file and the translation unit corresponding @@ -1436,15 +1415,11 @@ clang_parseTranslationUnit(CXIndex CIdx, * * \returns Zero on success, otherwise returns an error code. */ -CINDEX_LINKAGE enum CXErrorCode -clang_parseTranslationUnit2(CXIndex CIdx, - const char *source_filename, - const char *const *command_line_args, - int num_command_line_args, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options, - CXTranslationUnit *out_TU); +CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2( + CXIndex CIdx, const char *source_filename, + const char *const *command_line_args, int num_command_line_args, + struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, + unsigned options, CXTranslationUnit *out_TU); /** * Same as clang_parseTranslationUnit2 but requires a full command line @@ -1623,14 +1598,14 @@ CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU); * \c clang_disposeTranslationUnit(TU). The error codes returned by this * routine are described by the \c CXErrorCode enum. */ -CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - unsigned options); +CINDEX_LINKAGE int +clang_reparseTranslationUnit(CXTranslationUnit TU, unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + unsigned options); /** - * Categorizes how memory is being used by a translation unit. - */ + * Categorizes how memory is being used by a translation unit. + */ enum CXTUResourceUsageKind { CXTUResourceUsage_AST = 1, CXTUResourceUsage_Identifiers = 2, @@ -1648,16 +1623,16 @@ enum CXTUResourceUsageKind { CXTUResourceUsage_Preprocessor_HeaderSearch = 14, CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST, CXTUResourceUsage_MEMORY_IN_BYTES_END = - CXTUResourceUsage_Preprocessor_HeaderSearch, + CXTUResourceUsage_Preprocessor_HeaderSearch, CXTUResourceUsage_First = CXTUResourceUsage_AST, CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch }; /** - * Returns the human-readable null-terminated C string that represents - * the name of the memory category. This string should never be freed. - */ + * Returns the human-readable null-terminated C string that represents + * the name of the memory category. This string should never be freed. + */ CINDEX_LINKAGE const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind); @@ -1670,8 +1645,8 @@ typedef struct CXTUResourceUsageEntry { } CXTUResourceUsageEntry; /** - * The memory usage of a CXTranslationUnit, broken into categories. - */ + * The memory usage of a CXTranslationUnit, broken into categories. + */ typedef struct CXTUResourceUsage { /* Private data member, used for queries. */ void *data; @@ -1686,10 +1661,11 @@ typedef struct CXTUResourceUsage { } CXTUResourceUsage; /** - * Return the memory usage of a translation unit. This object - * should be released with clang_disposeCXTUResourceUsage(). - */ -CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU); + * Return the memory usage of a translation unit. This object + * should be released with clang_disposeCXTUResourceUsage(). + */ +CINDEX_LINKAGE CXTUResourceUsage +clang_getCXTUResourceUsage(CXTranslationUnit TU); CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage); @@ -1704,24 +1680,21 @@ clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit); /** * Destroy the CXTargetInfo object. */ -CINDEX_LINKAGE void -clang_TargetInfo_dispose(CXTargetInfo Info); +CINDEX_LINKAGE void clang_TargetInfo_dispose(CXTargetInfo Info); /** * Get the normalized target triple as a string. * * Returns the empty string in case of any error. */ -CINDEX_LINKAGE CXString -clang_TargetInfo_getTriple(CXTargetInfo Info); +CINDEX_LINKAGE CXString clang_TargetInfo_getTriple(CXTargetInfo Info); /** * Get the pointer width of the target in bits. * * Returns -1 in case of error. */ -CINDEX_LINKAGE int -clang_TargetInfo_getPointerWidth(CXTargetInfo Info); +CINDEX_LINKAGE int clang_TargetInfo_getPointerWidth(CXTargetInfo Info); /** * @} @@ -1741,95 +1714,95 @@ enum CXCursorKind { * spelling, find their definitions, etc. However, the specific kind * of the declaration is not reported. */ - CXCursor_UnexposedDecl = 1, + CXCursor_UnexposedDecl = 1, /** A C or C++ struct. */ - CXCursor_StructDecl = 2, + CXCursor_StructDecl = 2, /** A C or C++ union. */ - CXCursor_UnionDecl = 3, + CXCursor_UnionDecl = 3, /** A C++ class. */ - CXCursor_ClassDecl = 4, + CXCursor_ClassDecl = 4, /** An enumeration. */ - CXCursor_EnumDecl = 5, + CXCursor_EnumDecl = 5, /** * A field (in C) or non-static data member (in C++) in a * struct, union, or C++ class. */ - CXCursor_FieldDecl = 6, + CXCursor_FieldDecl = 6, /** An enumerator constant. */ - CXCursor_EnumConstantDecl = 7, + CXCursor_EnumConstantDecl = 7, /** A function. */ - CXCursor_FunctionDecl = 8, + CXCursor_FunctionDecl = 8, /** A variable. */ - CXCursor_VarDecl = 9, + CXCursor_VarDecl = 9, /** A function or method parameter. */ - CXCursor_ParmDecl = 10, + CXCursor_ParmDecl = 10, /** An Objective-C \@interface. */ - CXCursor_ObjCInterfaceDecl = 11, + CXCursor_ObjCInterfaceDecl = 11, /** An Objective-C \@interface for a category. */ - CXCursor_ObjCCategoryDecl = 12, + CXCursor_ObjCCategoryDecl = 12, /** An Objective-C \@protocol declaration. */ - CXCursor_ObjCProtocolDecl = 13, + CXCursor_ObjCProtocolDecl = 13, /** An Objective-C \@property declaration. */ - CXCursor_ObjCPropertyDecl = 14, + CXCursor_ObjCPropertyDecl = 14, /** An Objective-C instance variable. */ - CXCursor_ObjCIvarDecl = 15, + CXCursor_ObjCIvarDecl = 15, /** An Objective-C instance method. */ - CXCursor_ObjCInstanceMethodDecl = 16, + CXCursor_ObjCInstanceMethodDecl = 16, /** An Objective-C class method. */ - CXCursor_ObjCClassMethodDecl = 17, + CXCursor_ObjCClassMethodDecl = 17, /** An Objective-C \@implementation. */ - CXCursor_ObjCImplementationDecl = 18, + CXCursor_ObjCImplementationDecl = 18, /** An Objective-C \@implementation for a category. */ - CXCursor_ObjCCategoryImplDecl = 19, + CXCursor_ObjCCategoryImplDecl = 19, /** A typedef. */ - CXCursor_TypedefDecl = 20, + CXCursor_TypedefDecl = 20, /** A C++ class method. */ - CXCursor_CXXMethod = 21, + CXCursor_CXXMethod = 21, /** A C++ namespace. */ - CXCursor_Namespace = 22, + CXCursor_Namespace = 22, /** A linkage specification, e.g. 'extern "C"'. */ - CXCursor_LinkageSpec = 23, + CXCursor_LinkageSpec = 23, /** A C++ constructor. */ - CXCursor_Constructor = 24, + CXCursor_Constructor = 24, /** A C++ destructor. */ - CXCursor_Destructor = 25, + CXCursor_Destructor = 25, /** A C++ conversion function. */ - CXCursor_ConversionFunction = 26, + CXCursor_ConversionFunction = 26, /** A C++ template type parameter. */ - CXCursor_TemplateTypeParameter = 27, + CXCursor_TemplateTypeParameter = 27, /** A C++ non-type template parameter. */ - CXCursor_NonTypeTemplateParameter = 28, + CXCursor_NonTypeTemplateParameter = 28, /** A C++ template template parameter. */ - CXCursor_TemplateTemplateParameter = 29, + CXCursor_TemplateTemplateParameter = 29, /** A C++ function template. */ - CXCursor_FunctionTemplate = 30, + CXCursor_FunctionTemplate = 30, /** A C++ class template. */ - CXCursor_ClassTemplate = 31, + CXCursor_ClassTemplate = 31, /** A C++ class template partial specialization. */ CXCursor_ClassTemplatePartialSpecialization = 32, /** A C++ namespace alias declaration. */ - CXCursor_NamespaceAlias = 33, + CXCursor_NamespaceAlias = 33, /** A C++ using directive. */ - CXCursor_UsingDirective = 34, + CXCursor_UsingDirective = 34, /** A C++ using declaration. */ - CXCursor_UsingDeclaration = 35, + CXCursor_UsingDeclaration = 35, /** A C++ alias declaration */ - CXCursor_TypeAliasDecl = 36, + CXCursor_TypeAliasDecl = 36, /** An Objective-C \@synthesize definition. */ - CXCursor_ObjCSynthesizeDecl = 37, + CXCursor_ObjCSynthesizeDecl = 37, /** An Objective-C \@dynamic definition. */ - CXCursor_ObjCDynamicDecl = 38, + CXCursor_ObjCDynamicDecl = 38, /** An access specifier. */ - CXCursor_CXXAccessSpecifier = 39, + CXCursor_CXXAccessSpecifier = 39, - CXCursor_FirstDecl = CXCursor_UnexposedDecl, - CXCursor_LastDecl = CXCursor_CXXAccessSpecifier, + CXCursor_FirstDecl = CXCursor_UnexposedDecl, + CXCursor_LastDecl = CXCursor_CXXAccessSpecifier, /* References */ - CXCursor_FirstRef = 40, /* Decl references */ - CXCursor_ObjCSuperClassRef = 40, - CXCursor_ObjCProtocolRef = 41, - CXCursor_ObjCClassRef = 42, + CXCursor_FirstRef = 40, /* Decl references */ + CXCursor_ObjCSuperClassRef = 40, + CXCursor_ObjCProtocolRef = 41, + CXCursor_ObjCClassRef = 42, /** * A reference to a type declaration. * @@ -1845,22 +1818,22 @@ enum CXCursorKind { * while the type of the variable "size" is referenced. The cursor * referenced by the type of size is the typedef for size_type. */ - CXCursor_TypeRef = 43, - CXCursor_CXXBaseSpecifier = 44, + CXCursor_TypeRef = 43, + CXCursor_CXXBaseSpecifier = 44, /** * A reference to a class template, function template, template * template parameter, or class template partial specialization. */ - CXCursor_TemplateRef = 45, + CXCursor_TemplateRef = 45, /** * A reference to a namespace or namespace alias. */ - CXCursor_NamespaceRef = 46, + CXCursor_NamespaceRef = 46, /** * A reference to a member of a struct, union, or class that occurs in * some non-expression context, e.g., a designated initializer. */ - CXCursor_MemberRef = 47, + CXCursor_MemberRef = 47, /** * A reference to a labeled statement. * @@ -1876,7 +1849,7 @@ enum CXCursorKind { * * A label reference cursor refers to a label statement. */ - CXCursor_LabelRef = 48, + CXCursor_LabelRef = 48, /** * A reference to a set of overloaded functions or function templates @@ -1914,26 +1887,26 @@ enum CXCursorKind { * \c clang_getOverloadedDecl() can be used to retrieve the definitions * referenced by this cursor. */ - CXCursor_OverloadedDeclRef = 49, + CXCursor_OverloadedDeclRef = 49, /** * A reference to a variable that occurs in some non-expression * context, e.g., a C++ lambda capture list. */ - CXCursor_VariableRef = 50, + CXCursor_VariableRef = 50, - CXCursor_LastRef = CXCursor_VariableRef, + CXCursor_LastRef = CXCursor_VariableRef, /* Error conditions */ - CXCursor_FirstInvalid = 70, - CXCursor_InvalidFile = 70, - CXCursor_NoDeclFound = 71, - CXCursor_NotImplemented = 72, - CXCursor_InvalidCode = 73, - CXCursor_LastInvalid = CXCursor_InvalidCode, + CXCursor_FirstInvalid = 70, + CXCursor_InvalidFile = 70, + CXCursor_NoDeclFound = 71, + CXCursor_NotImplemented = 72, + CXCursor_InvalidCode = 73, + CXCursor_LastInvalid = CXCursor_InvalidCode, /* Expressions */ - CXCursor_FirstExpr = 100, + CXCursor_FirstExpr = 100, /** * An expression whose specific kind is not exposed via this @@ -1944,104 +1917,104 @@ enum CXCursorKind { * spelling, children, etc. However, the specific kind of the * expression is not reported. */ - CXCursor_UnexposedExpr = 100, + CXCursor_UnexposedExpr = 100, /** * An expression that refers to some value declaration, such * as a function, variable, or enumerator. */ - CXCursor_DeclRefExpr = 101, + CXCursor_DeclRefExpr = 101, /** * An expression that refers to a member of a struct, union, * class, Objective-C class, etc. */ - CXCursor_MemberRefExpr = 102, + CXCursor_MemberRefExpr = 102, /** An expression that calls a function. */ - CXCursor_CallExpr = 103, + CXCursor_CallExpr = 103, /** An expression that sends a message to an Objective-C object or class. */ - CXCursor_ObjCMessageExpr = 104, + CXCursor_ObjCMessageExpr = 104, /** An expression that represents a block literal. */ - CXCursor_BlockExpr = 105, + CXCursor_BlockExpr = 105, /** An integer literal. */ - CXCursor_IntegerLiteral = 106, + CXCursor_IntegerLiteral = 106, /** A floating point number literal. */ - CXCursor_FloatingLiteral = 107, + CXCursor_FloatingLiteral = 107, /** An imaginary number literal. */ - CXCursor_ImaginaryLiteral = 108, + CXCursor_ImaginaryLiteral = 108, /** A string literal. */ - CXCursor_StringLiteral = 109, + CXCursor_StringLiteral = 109, /** A character literal. */ - CXCursor_CharacterLiteral = 110, + CXCursor_CharacterLiteral = 110, /** A parenthesized expression, e.g. "(1)". * * This AST node is only formed if full location information is requested. */ - CXCursor_ParenExpr = 111, + CXCursor_ParenExpr = 111, /** This represents the unary-expression's (except sizeof and * alignof). */ - CXCursor_UnaryOperator = 112, + CXCursor_UnaryOperator = 112, /** [C99 6.5.2.1] Array Subscripting. */ - CXCursor_ArraySubscriptExpr = 113, + CXCursor_ArraySubscriptExpr = 113, /** A builtin binary operation expression such as "x + y" or * "x <= y". */ - CXCursor_BinaryOperator = 114, + CXCursor_BinaryOperator = 114, /** Compound assignment such as "+=". */ - CXCursor_CompoundAssignOperator = 115, + CXCursor_CompoundAssignOperator = 115, /** The ?: ternary operator. */ - CXCursor_ConditionalOperator = 116, + CXCursor_ConditionalOperator = 116, /** An explicit cast in C (C99 6.5.4) or a C-style cast in C++ * (C++ [expr.cast]), which uses the syntax (Type)expr. * * For example: (int)f. */ - CXCursor_CStyleCastExpr = 117, + CXCursor_CStyleCastExpr = 117, /** [C99 6.5.2.5] */ - CXCursor_CompoundLiteralExpr = 118, + CXCursor_CompoundLiteralExpr = 118, /** Describes an C or C++ initializer list. */ - CXCursor_InitListExpr = 119, + CXCursor_InitListExpr = 119, /** The GNU address of label extension, representing &&label. */ - CXCursor_AddrLabelExpr = 120, + CXCursor_AddrLabelExpr = 120, /** This is the GNU Statement Expression extension: ({int X=4; X;}) */ - CXCursor_StmtExpr = 121, + CXCursor_StmtExpr = 121, /** Represents a C11 generic selection. */ - CXCursor_GenericSelectionExpr = 122, + CXCursor_GenericSelectionExpr = 122, /** Implements the GNU __null extension, which is a name for a null * pointer constant that has integral type (e.g., int or long) and is the same @@ -2051,23 +2024,23 @@ enum CXCursorKind { * NULL as __null in C++ rather than using 0 (which is an integer that may not * match the size of a pointer). */ - CXCursor_GNUNullExpr = 123, + CXCursor_GNUNullExpr = 123, /** C++'s static_cast<> expression. */ - CXCursor_CXXStaticCastExpr = 124, + CXCursor_CXXStaticCastExpr = 124, /** C++'s dynamic_cast<> expression. */ - CXCursor_CXXDynamicCastExpr = 125, + CXCursor_CXXDynamicCastExpr = 125, /** C++'s reinterpret_cast<> expression. */ - CXCursor_CXXReinterpretCastExpr = 126, + CXCursor_CXXReinterpretCastExpr = 126, /** C++'s const_cast<> expression. */ - CXCursor_CXXConstCastExpr = 127, + CXCursor_CXXConstCastExpr = 127, /** Represents an explicit C++ type conversion that uses "functional" * notion (C++ [expr.type.conv]). @@ -2077,60 +2050,60 @@ enum CXCursorKind { * x = int(0.5); * \endcode */ - CXCursor_CXXFunctionalCastExpr = 128, + CXCursor_CXXFunctionalCastExpr = 128, /** A C++ typeid expression (C++ [expr.typeid]). */ - CXCursor_CXXTypeidExpr = 129, + CXCursor_CXXTypeidExpr = 129, /** [C++ 2.13.5] C++ Boolean Literal. */ - CXCursor_CXXBoolLiteralExpr = 130, + CXCursor_CXXBoolLiteralExpr = 130, /** [C++0x 2.14.7] C++ Pointer Literal. */ - CXCursor_CXXNullPtrLiteralExpr = 131, + CXCursor_CXXNullPtrLiteralExpr = 131, /** Represents the "this" expression in C++ */ - CXCursor_CXXThisExpr = 132, + 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 = 133, + CXCursor_CXXThrowExpr = 133, /** A new expression for memory allocation and constructor calls, e.g: * "new CXXNewExpr(foo)". */ - CXCursor_CXXNewExpr = 134, + CXCursor_CXXNewExpr = 134, /** A delete expression for memory deallocation and destructor calls, * e.g. "delete[] pArray". */ - CXCursor_CXXDeleteExpr = 135, + CXCursor_CXXDeleteExpr = 135, /** A unary expression. (noexcept, sizeof, or other traits) */ - CXCursor_UnaryExpr = 136, + CXCursor_UnaryExpr = 136, /** An Objective-C string literal i.e. @"foo". */ - CXCursor_ObjCStringLiteral = 137, + CXCursor_ObjCStringLiteral = 137, /** An Objective-C \@encode expression. */ - CXCursor_ObjCEncodeExpr = 138, + CXCursor_ObjCEncodeExpr = 138, /** An Objective-C \@selector expression. */ - CXCursor_ObjCSelectorExpr = 139, + CXCursor_ObjCSelectorExpr = 139, /** An Objective-C \@protocol expression. */ - CXCursor_ObjCProtocolExpr = 140, + CXCursor_ObjCProtocolExpr = 140, /** An Objective-C "bridged" cast expression, which casts between * Objective-C pointers and C pointers, transferring ownership in the process. @@ -2139,7 +2112,7 @@ enum CXCursorKind { * NSString *str = (__bridge_transfer NSString *)CFCreateString(); * \endcode */ - CXCursor_ObjCBridgedCastExpr = 141, + CXCursor_ObjCBridgedCastExpr = 141, /** Represents a C++0x pack expansion that produces a sequence of * expressions. @@ -2154,7 +2127,7 @@ enum CXCursorKind { * } * \endcode */ - CXCursor_PackExpansionExpr = 142, + CXCursor_PackExpansionExpr = 142, /** Represents an expression that computes the length of a parameter * pack. @@ -2166,7 +2139,7 @@ enum CXCursorKind { * }; * \endcode */ - CXCursor_SizeOfPackExpr = 143, + CXCursor_SizeOfPackExpr = 143, /* Represents a C++ lambda expression that produces a local function * object. @@ -2180,33 +2153,46 @@ enum CXCursorKind { * } * \endcode */ - CXCursor_LambdaExpr = 144, + CXCursor_LambdaExpr = 144, /** Objective-c Boolean Literal. */ - CXCursor_ObjCBoolLiteralExpr = 145, + CXCursor_ObjCBoolLiteralExpr = 145, /** Represents the "self" expression in an Objective-C method. */ - CXCursor_ObjCSelfExpr = 146, + CXCursor_ObjCSelfExpr = 146, - /** OpenMP 4.0 [2.4, Array Section]. + /** OpenMP 5.0 [2.1.5, Array Section]. */ - CXCursor_OMPArraySectionExpr = 147, + CXCursor_OMPArraySectionExpr = 147, /** Represents an @available(...) check. */ - CXCursor_ObjCAvailabilityCheckExpr = 148, + CXCursor_ObjCAvailabilityCheckExpr = 148, /** * Fixed point literal */ - CXCursor_FixedPointLiteral = 149, + CXCursor_FixedPointLiteral = 149, + + /** OpenMP 5.0 [2.1.4, Array Shaping]. + */ + CXCursor_OMPArrayShapingExpr = 150, + + /** + * OpenMP 5.0 [2.1.6 Iterators] + */ + CXCursor_OMPIteratorExpr = 151, + + /** OpenCL's addrspace_cast<> expression. + */ + CXCursor_CXXAddrspaceCastExpr = 152, - CXCursor_LastExpr = CXCursor_FixedPointLiteral, + CXCursor_LastExpr = CXCursor_CXXAddrspaceCastExpr, /* Statements */ - CXCursor_FirstStmt = 200, + CXCursor_FirstStmt = 200, /** * A statement whose specific kind is not exposed via this * interface. @@ -2216,7 +2202,7 @@ enum CXCursorKind { * children, etc. However, the specific kind of the statement is not * reported. */ - CXCursor_UnexposedStmt = 200, + CXCursor_UnexposedStmt = 200, /** A labelled statement in a function. * @@ -2229,226 +2215,226 @@ enum CXCursorKind { * \endcode * */ - CXCursor_LabelStmt = 201, + CXCursor_LabelStmt = 201, /** A group of statements like { stmt stmt }. * * This cursor kind is used to describe compound statements, e.g. function * bodies. */ - CXCursor_CompoundStmt = 202, + CXCursor_CompoundStmt = 202, /** A case statement. */ - CXCursor_CaseStmt = 203, + CXCursor_CaseStmt = 203, /** A default statement. */ - CXCursor_DefaultStmt = 204, + CXCursor_DefaultStmt = 204, /** An if statement */ - CXCursor_IfStmt = 205, + CXCursor_IfStmt = 205, /** A switch statement. */ - CXCursor_SwitchStmt = 206, + CXCursor_SwitchStmt = 206, /** A while statement. */ - CXCursor_WhileStmt = 207, + CXCursor_WhileStmt = 207, /** A do statement. */ - CXCursor_DoStmt = 208, + CXCursor_DoStmt = 208, /** A for statement. */ - CXCursor_ForStmt = 209, + CXCursor_ForStmt = 209, /** A goto statement. */ - CXCursor_GotoStmt = 210, + CXCursor_GotoStmt = 210, /** An indirect goto statement. */ - CXCursor_IndirectGotoStmt = 211, + CXCursor_IndirectGotoStmt = 211, /** A continue statement. */ - CXCursor_ContinueStmt = 212, + CXCursor_ContinueStmt = 212, /** A break statement. */ - CXCursor_BreakStmt = 213, + CXCursor_BreakStmt = 213, /** A return statement. */ - CXCursor_ReturnStmt = 214, + CXCursor_ReturnStmt = 214, /** A GCC inline assembly statement extension. */ - CXCursor_GCCAsmStmt = 215, - CXCursor_AsmStmt = CXCursor_GCCAsmStmt, + CXCursor_GCCAsmStmt = 215, + CXCursor_AsmStmt = CXCursor_GCCAsmStmt, /** Objective-C's overall \@try-\@catch-\@finally statement. */ - CXCursor_ObjCAtTryStmt = 216, + CXCursor_ObjCAtTryStmt = 216, /** Objective-C's \@catch statement. */ - CXCursor_ObjCAtCatchStmt = 217, + CXCursor_ObjCAtCatchStmt = 217, /** Objective-C's \@finally statement. */ - CXCursor_ObjCAtFinallyStmt = 218, + CXCursor_ObjCAtFinallyStmt = 218, /** Objective-C's \@throw statement. */ - CXCursor_ObjCAtThrowStmt = 219, + CXCursor_ObjCAtThrowStmt = 219, /** Objective-C's \@synchronized statement. */ - CXCursor_ObjCAtSynchronizedStmt = 220, + CXCursor_ObjCAtSynchronizedStmt = 220, /** Objective-C's autorelease pool statement. */ - CXCursor_ObjCAutoreleasePoolStmt = 221, + CXCursor_ObjCAutoreleasePoolStmt = 221, /** Objective-C's collection statement. */ - CXCursor_ObjCForCollectionStmt = 222, + CXCursor_ObjCForCollectionStmt = 222, /** C++'s catch statement. */ - CXCursor_CXXCatchStmt = 223, + CXCursor_CXXCatchStmt = 223, /** C++'s try statement. */ - CXCursor_CXXTryStmt = 224, + CXCursor_CXXTryStmt = 224, /** C++'s for (* : *) statement. */ - CXCursor_CXXForRangeStmt = 225, + CXCursor_CXXForRangeStmt = 225, /** Windows Structured Exception Handling's try statement. */ - CXCursor_SEHTryStmt = 226, + CXCursor_SEHTryStmt = 226, /** Windows Structured Exception Handling's except statement. */ - CXCursor_SEHExceptStmt = 227, + CXCursor_SEHExceptStmt = 227, /** Windows Structured Exception Handling's finally statement. */ - CXCursor_SEHFinallyStmt = 228, + CXCursor_SEHFinallyStmt = 228, /** A MS inline assembly statement extension. */ - CXCursor_MSAsmStmt = 229, + CXCursor_MSAsmStmt = 229, /** The null statement ";": C99 6.8.3p3. * * This cursor kind is used to describe the null statement. */ - CXCursor_NullStmt = 230, + CXCursor_NullStmt = 230, /** Adaptor class for mixing declarations with statements and * expressions. */ - CXCursor_DeclStmt = 231, + CXCursor_DeclStmt = 231, /** OpenMP parallel directive. */ - CXCursor_OMPParallelDirective = 232, + CXCursor_OMPParallelDirective = 232, /** OpenMP SIMD directive. */ - CXCursor_OMPSimdDirective = 233, + CXCursor_OMPSimdDirective = 233, /** OpenMP for directive. */ - CXCursor_OMPForDirective = 234, + CXCursor_OMPForDirective = 234, /** OpenMP sections directive. */ - CXCursor_OMPSectionsDirective = 235, + CXCursor_OMPSectionsDirective = 235, /** OpenMP section directive. */ - CXCursor_OMPSectionDirective = 236, + CXCursor_OMPSectionDirective = 236, /** OpenMP single directive. */ - CXCursor_OMPSingleDirective = 237, + CXCursor_OMPSingleDirective = 237, /** OpenMP parallel for directive. */ - CXCursor_OMPParallelForDirective = 238, + CXCursor_OMPParallelForDirective = 238, /** OpenMP parallel sections directive. */ - CXCursor_OMPParallelSectionsDirective = 239, + CXCursor_OMPParallelSectionsDirective = 239, /** OpenMP task directive. */ - CXCursor_OMPTaskDirective = 240, + CXCursor_OMPTaskDirective = 240, /** OpenMP master directive. */ - CXCursor_OMPMasterDirective = 241, + CXCursor_OMPMasterDirective = 241, /** OpenMP critical directive. */ - CXCursor_OMPCriticalDirective = 242, + CXCursor_OMPCriticalDirective = 242, /** OpenMP taskyield directive. */ - CXCursor_OMPTaskyieldDirective = 243, + CXCursor_OMPTaskyieldDirective = 243, /** OpenMP barrier directive. */ - CXCursor_OMPBarrierDirective = 244, + CXCursor_OMPBarrierDirective = 244, /** OpenMP taskwait directive. */ - CXCursor_OMPTaskwaitDirective = 245, + CXCursor_OMPTaskwaitDirective = 245, /** OpenMP flush directive. */ - CXCursor_OMPFlushDirective = 246, + CXCursor_OMPFlushDirective = 246, /** Windows Structured Exception Handling's leave statement. */ - CXCursor_SEHLeaveStmt = 247, + CXCursor_SEHLeaveStmt = 247, /** OpenMP ordered directive. */ - CXCursor_OMPOrderedDirective = 248, + CXCursor_OMPOrderedDirective = 248, /** OpenMP atomic directive. */ - CXCursor_OMPAtomicDirective = 249, + CXCursor_OMPAtomicDirective = 249, /** OpenMP for SIMD directive. */ - CXCursor_OMPForSimdDirective = 250, + CXCursor_OMPForSimdDirective = 250, /** OpenMP parallel for SIMD directive. */ - CXCursor_OMPParallelForSimdDirective = 251, + CXCursor_OMPParallelForSimdDirective = 251, /** OpenMP target directive. */ - CXCursor_OMPTargetDirective = 252, + CXCursor_OMPTargetDirective = 252, /** OpenMP teams directive. */ - CXCursor_OMPTeamsDirective = 253, + CXCursor_OMPTeamsDirective = 253, /** OpenMP taskgroup directive. */ - CXCursor_OMPTaskgroupDirective = 254, + CXCursor_OMPTaskgroupDirective = 254, /** OpenMP cancellation point directive. */ @@ -2456,35 +2442,35 @@ enum CXCursorKind { /** OpenMP cancel directive. */ - CXCursor_OMPCancelDirective = 256, + CXCursor_OMPCancelDirective = 256, /** OpenMP target data directive. */ - CXCursor_OMPTargetDataDirective = 257, + CXCursor_OMPTargetDataDirective = 257, /** OpenMP taskloop directive. */ - CXCursor_OMPTaskLoopDirective = 258, + CXCursor_OMPTaskLoopDirective = 258, /** OpenMP taskloop simd directive. */ - CXCursor_OMPTaskLoopSimdDirective = 259, + CXCursor_OMPTaskLoopSimdDirective = 259, /** OpenMP distribute directive. */ - CXCursor_OMPDistributeDirective = 260, + CXCursor_OMPDistributeDirective = 260, /** OpenMP target enter data directive. */ - CXCursor_OMPTargetEnterDataDirective = 261, + CXCursor_OMPTargetEnterDataDirective = 261, /** OpenMP target exit data directive. */ - CXCursor_OMPTargetExitDataDirective = 262, + CXCursor_OMPTargetExitDataDirective = 262, /** OpenMP target parallel directive. */ - CXCursor_OMPTargetParallelDirective = 263, + CXCursor_OMPTargetParallelDirective = 263, /** OpenMP target parallel for directive. */ @@ -2492,7 +2478,7 @@ enum CXCursorKind { /** OpenMP target update directive. */ - CXCursor_OMPTargetUpdateDirective = 265, + CXCursor_OMPTargetUpdateDirective = 265, /** OpenMP distribute parallel for directive. */ @@ -2564,17 +2550,25 @@ enum CXCursorKind { /** OpenMP master taskloop simd directive. */ - CXCursor_OMPMasterTaskLoopSimdDirective = 283, + CXCursor_OMPMasterTaskLoopSimdDirective = 283, /** OpenMP parallel master taskloop simd directive. */ - CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284, + CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284, /** OpenMP parallel master directive. */ - CXCursor_OMPParallelMasterDirective = 285, + CXCursor_OMPParallelMasterDirective = 285, + + /** OpenMP depobj directive. + */ + CXCursor_OMPDepobjDirective = 286, + + /** OpenMP scan directive. + */ + CXCursor_OMPScanDirective = 287, - CXCursor_LastStmt = CXCursor_OMPParallelMasterDirective, + CXCursor_LastStmt = CXCursor_OMPScanDirective, /** * Cursor that represents the translation unit itself. @@ -2582,89 +2576,89 @@ enum CXCursorKind { * The translation unit cursor exists primarily to act as the root * cursor for traversing the contents of a translation unit. */ - CXCursor_TranslationUnit = 300, + CXCursor_TranslationUnit = 300, /* Attributes */ - CXCursor_FirstAttr = 400, + CXCursor_FirstAttr = 400, /** * An attribute whose specific kind is not exposed via this * interface. */ - CXCursor_UnexposedAttr = 400, - - CXCursor_IBActionAttr = 401, - CXCursor_IBOutletAttr = 402, - CXCursor_IBOutletCollectionAttr = 403, - CXCursor_CXXFinalAttr = 404, - CXCursor_CXXOverrideAttr = 405, - CXCursor_AnnotateAttr = 406, - CXCursor_AsmLabelAttr = 407, - CXCursor_PackedAttr = 408, - CXCursor_PureAttr = 409, - CXCursor_ConstAttr = 410, - CXCursor_NoDuplicateAttr = 411, - CXCursor_CUDAConstantAttr = 412, - CXCursor_CUDADeviceAttr = 413, - CXCursor_CUDAGlobalAttr = 414, - CXCursor_CUDAHostAttr = 415, - CXCursor_CUDASharedAttr = 416, - CXCursor_VisibilityAttr = 417, - CXCursor_DLLExport = 418, - CXCursor_DLLImport = 419, - CXCursor_NSReturnsRetained = 420, - CXCursor_NSReturnsNotRetained = 421, - CXCursor_NSReturnsAutoreleased = 422, - CXCursor_NSConsumesSelf = 423, - CXCursor_NSConsumed = 424, - CXCursor_ObjCException = 425, - CXCursor_ObjCNSObject = 426, - CXCursor_ObjCIndependentClass = 427, - CXCursor_ObjCPreciseLifetime = 428, - CXCursor_ObjCReturnsInnerPointer = 429, - CXCursor_ObjCRequiresSuper = 430, - CXCursor_ObjCRootClass = 431, - CXCursor_ObjCSubclassingRestricted = 432, - CXCursor_ObjCExplicitProtocolImpl = 433, - CXCursor_ObjCDesignatedInitializer = 434, - CXCursor_ObjCRuntimeVisible = 435, - CXCursor_ObjCBoxable = 436, - CXCursor_FlagEnum = 437, - CXCursor_ConvergentAttr = 438, - CXCursor_WarnUnusedAttr = 439, - CXCursor_WarnUnusedResultAttr = 440, - CXCursor_AlignedAttr = 441, - CXCursor_LastAttr = CXCursor_AlignedAttr, + CXCursor_UnexposedAttr = 400, + + CXCursor_IBActionAttr = 401, + CXCursor_IBOutletAttr = 402, + CXCursor_IBOutletCollectionAttr = 403, + CXCursor_CXXFinalAttr = 404, + CXCursor_CXXOverrideAttr = 405, + CXCursor_AnnotateAttr = 406, + CXCursor_AsmLabelAttr = 407, + CXCursor_PackedAttr = 408, + CXCursor_PureAttr = 409, + CXCursor_ConstAttr = 410, + CXCursor_NoDuplicateAttr = 411, + CXCursor_CUDAConstantAttr = 412, + CXCursor_CUDADeviceAttr = 413, + CXCursor_CUDAGlobalAttr = 414, + CXCursor_CUDAHostAttr = 415, + CXCursor_CUDASharedAttr = 416, + CXCursor_VisibilityAttr = 417, + CXCursor_DLLExport = 418, + CXCursor_DLLImport = 419, + CXCursor_NSReturnsRetained = 420, + CXCursor_NSReturnsNotRetained = 421, + CXCursor_NSReturnsAutoreleased = 422, + CXCursor_NSConsumesSelf = 423, + CXCursor_NSConsumed = 424, + CXCursor_ObjCException = 425, + CXCursor_ObjCNSObject = 426, + CXCursor_ObjCIndependentClass = 427, + CXCursor_ObjCPreciseLifetime = 428, + CXCursor_ObjCReturnsInnerPointer = 429, + CXCursor_ObjCRequiresSuper = 430, + CXCursor_ObjCRootClass = 431, + CXCursor_ObjCSubclassingRestricted = 432, + CXCursor_ObjCExplicitProtocolImpl = 433, + CXCursor_ObjCDesignatedInitializer = 434, + CXCursor_ObjCRuntimeVisible = 435, + CXCursor_ObjCBoxable = 436, + CXCursor_FlagEnum = 437, + CXCursor_ConvergentAttr = 438, + CXCursor_WarnUnusedAttr = 439, + CXCursor_WarnUnusedResultAttr = 440, + CXCursor_AlignedAttr = 441, + CXCursor_LastAttr = CXCursor_AlignedAttr, /* Preprocessing */ - CXCursor_PreprocessingDirective = 500, - CXCursor_MacroDefinition = 501, - CXCursor_MacroExpansion = 502, - CXCursor_MacroInstantiation = CXCursor_MacroExpansion, - CXCursor_InclusionDirective = 503, - CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, - CXCursor_LastPreprocessing = CXCursor_InclusionDirective, + CXCursor_PreprocessingDirective = 500, + CXCursor_MacroDefinition = 501, + CXCursor_MacroExpansion = 502, + CXCursor_MacroInstantiation = CXCursor_MacroExpansion, + CXCursor_InclusionDirective = 503, + CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, + CXCursor_LastPreprocessing = CXCursor_InclusionDirective, /* Extra Declarations */ /** * A module import declaration. */ - CXCursor_ModuleImportDecl = 600, - CXCursor_TypeAliasTemplateDecl = 601, + CXCursor_ModuleImportDecl = 600, + CXCursor_TypeAliasTemplateDecl = 601, /** * A static_assert or _Static_assert node */ - CXCursor_StaticAssert = 602, + CXCursor_StaticAssert = 602, /** * a friend declaration. */ - CXCursor_FriendDecl = 603, - CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, - CXCursor_LastExtraDecl = CXCursor_FriendDecl, + CXCursor_FriendDecl = 603, + CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, + CXCursor_LastExtraDecl = CXCursor_FriendDecl, /** * A code completion overload candidate. */ - CXCursor_OverloadCandidate = 700 + CXCursor_OverloadCandidate = 700 }; /** @@ -2935,14 +2929,10 @@ typedef struct CXPlatformAvailability { * platform-availability structures returned. There are * \c min(N, availability_size) such structures. */ -CINDEX_LINKAGE int -clang_getCursorPlatformAvailability(CXCursor cursor, - int *always_deprecated, - CXString *deprecated_message, - int *always_unavailable, - CXString *unavailable_message, - CXPlatformAvailability *availability, - int availability_size); +CINDEX_LINKAGE int clang_getCursorPlatformAvailability( + CXCursor cursor, int *always_deprecated, CXString *deprecated_message, + int *always_unavailable, CXString *unavailable_message, + CXPlatformAvailability *availability, int availability_size); /** * Free the memory associated with a \c CXPlatformAvailability structure. @@ -2969,11 +2959,7 @@ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); * Describe the "thread-local storage (TLS) kind" of the declaration * referred to by a cursor. */ -enum CXTLSKind { - CXTLS_None = 0, - CXTLS_Dynamic, - CXTLS_Static -}; +enum CXTLSKind { CXTLS_None = 0, CXTLS_Dynamic, CXTLS_Static }; /** * Determine the "thread-local storage (TLS) kind" of the declaration @@ -3005,7 +2991,7 @@ CINDEX_LINKAGE void clang_disposeCXCursorSet(CXCursorSet cset); * Queries a CXCursorSet to see if it contains a specific CXCursor. * * \returns non-zero if the set contains the specified cursor. -*/ + */ CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset, CXCursor cursor); @@ -3013,7 +2999,7 @@ CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset, * Inserts a CXCursor into a CXCursorSet. * * \returns zero if the CXCursor was already in the set, and non-zero otherwise. -*/ + */ CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset, CXCursor cursor); @@ -3267,8 +3253,9 @@ enum CXTypeKind { CXType_UShortAccum = 36, CXType_UAccum = 37, CXType_ULongAccum = 38, + CXType_BFloat16 = 39, CXType_FirstBuiltin = CXType_Void, - CXType_LastBuiltin = CXType_ULongAccum, + CXType_LastBuiltin = CXType_BFloat16, CXType_Complex = 100, CXType_Pointer = 101, @@ -3360,7 +3347,8 @@ enum CXTypeKind { CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175, - CXType_ExtVector = 176 + CXType_ExtVector = 176, + CXType_Atomic = 177 }; /** @@ -3433,9 +3421,9 @@ CINDEX_LINKAGE CXType clang_getEnumDeclIntegerType(CXCursor C); * Retrieve the integer value of an enum constant declaration as a signed * long long. * - * If the cursor does not reference an enum constant declaration, LLONG_MIN is returned. - * Since this is also potentially a valid constant value, the kind of the cursor - * must be verified before calling this function. + * If the cursor does not reference an enum constant declaration, LLONG_MIN is + * returned. Since this is also potentially a valid constant value, the kind of + * the cursor must be verified before calling this function. */ CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C); @@ -3443,11 +3431,12 @@ CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C); * Retrieve the integer value of an enum constant declaration as an unsigned * long long. * - * If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned. - * Since this is also potentially a valid constant value, the kind of the cursor - * must be verified before calling this function. + * If the cursor does not reference an enum constant declaration, ULLONG_MAX is + * returned. Since this is also potentially a valid constant value, the kind of + * the cursor must be verified before calling this function. */ -CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C); +CINDEX_LINKAGE unsigned long long +clang_getEnumConstantDeclUnsignedValue(CXCursor C); /** * Retrieve the bit width of a bit field declaration as an integer. @@ -3528,8 +3517,8 @@ CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C); * For I = 0, 1, and 2, Type, Integral, and Integral will be returned, * respectively. */ -CINDEX_LINKAGE enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind( - CXCursor C, unsigned I); +CINDEX_LINKAGE enum CXTemplateArgumentKind +clang_Cursor_getTemplateArgumentKind(CXCursor C, unsigned I); /** * Retrieve a CXType representing the type of a TemplateArgument of a @@ -3589,8 +3578,8 @@ CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C, * If called with I = 1 or 2, 2147483649 or true will be returned, respectively. * For I == 0, this function's behavior is undefined. */ -CINDEX_LINKAGE unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue( - CXCursor C, unsigned I); +CINDEX_LINKAGE unsigned long long +clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C, unsigned I); /** * Determine whether two CXTypes represent the same type. @@ -3745,7 +3734,7 @@ CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T); CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i); /** - * Retreive the number of type arguments associated with an ObjC object. + * Retrieve the number of type arguments associated with an ObjC object. * * If the type is not an ObjC object, 0 is returned. */ @@ -3775,7 +3764,8 @@ CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C); * Retrieve the exception specification type associated with a given cursor. * This is a value of type CXCursor_ExceptionSpecificationKind. * - * This only returns a valid result if the cursor refers to a function or method. + * This only returns a valid result if the cursor refers to a function or + * method. */ CINDEX_LINKAGE int clang_getCursorExceptionSpecificationType(CXCursor C); @@ -3948,6 +3938,13 @@ CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S); */ CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T); +/** + * Gets the type contained by this atomic type. + * + * If a non-atomic type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); + /** * Return the offset of the field represented by the Cursor. * @@ -4003,7 +4000,8 @@ CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T); * This function only returns template type arguments and does not handle * template template arguments or variadic packs. */ -CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned i); +CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, + unsigned i); /** * Retrieve the ref-qualifier kind of a function or method. @@ -4039,9 +4037,9 @@ enum CX_CXXAccessSpecifier { /** * Returns the access control level for the referenced object. * - * If the cursor refers to a C++ declaration, its access control level within its - * parent scope is returned. Otherwise, if the cursor refers to a base specifier or - * access specifier, the specifier itself is returned. + * If the cursor refers to a C++ declaration, its access control level within + * its parent scope is returned. Otherwise, if the cursor refers to a base + * specifier or access specifier, the specifier itself is returned. */ CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor); @@ -4192,7 +4190,7 @@ CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data); #ifdef __has_feature -# if __has_feature(blocks) +#if __has_feature(blocks) /** * Visitor invoked for each cursor found by a traversal. * @@ -4203,16 +4201,16 @@ CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, * The visitor should return one of the \c CXChildVisitResult values * to direct clang_visitChildrenWithBlock(). */ -typedef enum CXChildVisitResult - (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); +typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor, + CXCursor parent); /** * Visits the children of a cursor using the specified block. Behaves * identically to clang_visitChildren() in all other respects. */ -CINDEX_LINKAGE unsigned clang_visitChildrenWithBlock(CXCursor parent, - CXCursorVisitorBlock block); -# endif +CINDEX_LINKAGE unsigned +clang_visitChildrenWithBlock(CXCursor parent, CXCursorVisitorBlock block); +#endif #endif /** @@ -4249,15 +4247,14 @@ CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name); /** * Construct a USR for a specified Objective-C category. */ -CINDEX_LINKAGE CXString - clang_constructUSR_ObjCCategory(const char *class_name, - const char *category_name); +CINDEX_LINKAGE CXString clang_constructUSR_ObjCCategory( + const char *class_name, const char *category_name); /** * Construct a USR for a specified Objective-C protocol. */ CINDEX_LINKAGE CXString - clang_constructUSR_ObjCProtocol(const char *protocol_name); +clang_constructUSR_ObjCProtocol(const char *protocol_name); /** * Construct a USR for a specified Objective-C instance variable and @@ -4297,9 +4294,8 @@ CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor); * * \param options Reserved. */ -CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor, - unsigned pieceIndex, - unsigned options); +CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange( + CXCursor, unsigned pieceIndex, unsigned options); /** * Opaque pointer representing a policy that controls pretty printing @@ -4353,9 +4349,10 @@ clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy, /** * Set a property value for the given printing policy. */ -CINDEX_LINKAGE void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, - enum CXPrintingPolicyProperty Property, - unsigned Value); +CINDEX_LINKAGE void +clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, + enum CXPrintingPolicyProperty Property, + unsigned Value); /** * Retrieve the default policy for the cursor. @@ -4503,18 +4500,18 @@ CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C); * Property attributes for a \c CXCursor_ObjCPropertyDecl. */ typedef enum { - CXObjCPropertyAttr_noattr = 0x00, - CXObjCPropertyAttr_readonly = 0x01, - CXObjCPropertyAttr_getter = 0x02, - CXObjCPropertyAttr_assign = 0x04, + CXObjCPropertyAttr_noattr = 0x00, + CXObjCPropertyAttr_readonly = 0x01, + CXObjCPropertyAttr_getter = 0x02, + CXObjCPropertyAttr_assign = 0x04, CXObjCPropertyAttr_readwrite = 0x08, - CXObjCPropertyAttr_retain = 0x10, - CXObjCPropertyAttr_copy = 0x20, + CXObjCPropertyAttr_retain = 0x10, + CXObjCPropertyAttr_copy = 0x20, CXObjCPropertyAttr_nonatomic = 0x40, - CXObjCPropertyAttr_setter = 0x80, - CXObjCPropertyAttr_atomic = 0x100, - CXObjCPropertyAttr_weak = 0x200, - CXObjCPropertyAttr_strong = 0x400, + CXObjCPropertyAttr_setter = 0x80, + CXObjCPropertyAttr_atomic = 0x100, + CXObjCPropertyAttr_weak = 0x200, + CXObjCPropertyAttr_strong = 0x400, CXObjCPropertyAttr_unsafe_unretained = 0x800, CXObjCPropertyAttr_class = 0x1000 } CXObjCPropertyAttrKind; @@ -4526,8 +4523,8 @@ typedef enum { * * \param reserved Reserved for future use, pass 0. */ -CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, - unsigned reserved); +CINDEX_LINKAGE unsigned +clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved); /** * Given a cursor that represents a property declaration, return the @@ -4589,8 +4586,9 @@ CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C); * non-zero if the 'generated_declaration' is set in the attribute. */ CINDEX_LINKAGE unsigned clang_Cursor_isExternalSymbol(CXCursor C, - CXString *language, CXString *definedIn, - unsigned *isGenerated); + CXString *language, + CXString *definedIn, + unsigned *isGenerated); /** * Given a cursor that represents a declaration, return the associated @@ -4716,8 +4714,8 @@ CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit, * \returns the specified top level header associated with the module. */ CINDEX_LINKAGE -CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, - CXModule Module, unsigned Index); +CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, CXModule Module, + unsigned Index); /** * @} @@ -4735,7 +4733,8 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, /** * Determine if a C++ constructor is a converting constructor. */ -CINDEX_LINKAGE unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C); +CINDEX_LINKAGE unsigned +clang_CXXConstructor_isConvertingConstructor(CXCursor C); /** * Determine if a C++ constructor is a copy constructor. @@ -4865,9 +4864,8 @@ CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C); * \returns The piece of the name pointed to by the given cursor. If there is no * name, or if the PieceIndex is out-of-range, a null-cursor will be returned. */ -CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, - unsigned NameFlags, - unsigned PieceIndex); +CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange( + CXCursor C, unsigned NameFlags, unsigned PieceIndex); enum CXNameRefFlags { /** @@ -5035,15 +5033,14 @@ CINDEX_LINKAGE void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, * \param Cursors an array of \p NumTokens cursors, whose contents will be * replaced with the cursors corresponding to each token. */ -CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens, - CXCursor *Cursors); +CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens, + unsigned NumTokens, CXCursor *Cursors); /** * Free the given set of tokens. */ -CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens); +CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens, + unsigned NumTokens); /** * @} @@ -5060,15 +5057,11 @@ CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU, /* for debug/testing */ CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind); -CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor, - const char **startBuf, - const char **endBuf, - unsigned *startLine, - unsigned *startColumn, - unsigned *endLine, - unsigned *endColumn); +CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent( + CXCursor, const char **startBuf, const char **endBuf, unsigned *startLine, + unsigned *startColumn, unsigned *endLine, unsigned *endColumn); CINDEX_LINKAGE void clang_enableStackTraces(void); -CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void*), void *user_data, +CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void *), void *user_data, unsigned stack_size); /** @@ -5319,9 +5312,8 @@ clang_getCompletionChunkKind(CXCompletionString completion_string, * * \returns the text associated with the chunk at index \c chunk_number. */ -CINDEX_LINKAGE CXString -clang_getCompletionChunkText(CXCompletionString completion_string, - unsigned chunk_number); +CINDEX_LINKAGE CXString clang_getCompletionChunkText( + CXCompletionString completion_string, unsigned chunk_number); /** * Retrieve the completion string associated with a particular chunk @@ -5334,9 +5326,8 @@ clang_getCompletionChunkText(CXCompletionString completion_string, * \returns the completion string associated with the chunk at index * \c chunk_number. */ -CINDEX_LINKAGE CXCompletionString -clang_getCompletionChunkCompletionString(CXCompletionString completion_string, - unsigned chunk_number); +CINDEX_LINKAGE CXCompletionString clang_getCompletionChunkCompletionString( + CXCompletionString completion_string, unsigned chunk_number); /** * Retrieve the number of chunks in the given code-completion string. @@ -5393,9 +5384,8 @@ clang_getCompletionNumAnnotations(CXCompletionString completion_string); * \returns annotation string associated with the completion at index * \c annotation_number, or a NULL string if that annotation is not available. */ -CINDEX_LINKAGE CXString -clang_getCompletionAnnotation(CXCompletionString completion_string, - unsigned annotation_number); +CINDEX_LINKAGE CXString clang_getCompletionAnnotation( + CXCompletionString completion_string, unsigned annotation_number); /** * Retrieve the parent context of the given completion string. @@ -5413,9 +5403,8 @@ clang_getCompletionAnnotation(CXCompletionString completion_string, * \returns The name of the completion parent, e.g., "NSObject" if * the completion string represents a method in the NSObject class. */ -CINDEX_LINKAGE CXString -clang_getCompletionParent(CXCompletionString completion_string, - enum CXCursorKind *kind); +CINDEX_LINKAGE CXString clang_getCompletionParent( + CXCompletionString completion_string, enum CXCursorKind *kind); /** * Retrieve the brief documentation comment attached to the declaration @@ -5771,13 +5760,11 @@ CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void); * completion fails, returns NULL. */ CINDEX_LINKAGE -CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, - const char *complete_filename, - unsigned complete_line, - unsigned complete_column, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options); +CXCodeCompleteResults * +clang_codeCompleteAt(CXTranslationUnit TU, const char *complete_filename, + unsigned complete_line, unsigned complete_column, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, unsigned options); /** * Sort the code-completion results in case-insensitive alphabetical @@ -5826,8 +5813,8 @@ CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results, * along with the given code completion results. */ CINDEX_LINKAGE -unsigned long long clang_codeCompleteGetContexts( - CXCodeCompleteResults *Results); +unsigned long long +clang_codeCompleteGetContexts(CXCodeCompleteResults *Results); /** * Returns the cursor kind for the container for the current code @@ -5846,9 +5833,9 @@ unsigned long long clang_codeCompleteGetContexts( * container */ CINDEX_LINKAGE -enum CXCursorKind clang_codeCompleteGetContainerKind( - CXCodeCompleteResults *Results, - unsigned *IsIncomplete); +enum CXCursorKind +clang_codeCompleteGetContainerKind(CXCodeCompleteResults *Results, + unsigned *IsIncomplete); /** * Returns the USR for the container for the current code completion @@ -5900,19 +5887,19 @@ CINDEX_LINKAGE CXString clang_getClangVersion(void); */ CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled); - /** - * Visitor invoked for each file in a translation unit - * (used with clang_getInclusions()). - * - * This visitor function will be invoked by clang_getInclusions() for each - * file included (either at the top-level or by \#include directives) within - * a translation unit. The first argument is the file being included, and - * the second and third arguments provide the inclusion stack. The - * array is sorted in order of immediate inclusion. For example, - * the first element refers to the location that included 'included_file'. - */ +/** + * Visitor invoked for each file in a translation unit + * (used with clang_getInclusions()). + * + * This visitor function will be invoked by clang_getInclusions() for each + * file included (either at the top-level or by \#include directives) within + * a translation unit. The first argument is the file being included, and + * the second and third arguments provide the inclusion stack. The + * array is sorted in order of immediate inclusion. For example, + * the first element refers to the location that included 'included_file'. + */ typedef void (*CXInclusionVisitor)(CXFile included_file, - CXSourceLocation* inclusion_stack, + CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data); @@ -5927,7 +5914,7 @@ CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu, CXClientData client_data); typedef enum { - CXEval_Int = 1 , + CXEval_Int = 1, CXEval_Float = 2, CXEval_ObjCStrLiteral = 3, CXEval_StrLiteral = 4, @@ -5936,17 +5923,18 @@ typedef enum { CXEval_UnExposed = 0 -} CXEvalResultKind ; +} CXEvalResultKind; /** * Evaluation result of a cursor */ -typedef void * CXEvalResult; +typedef void *CXEvalResult; /** * If cursor is a statement declaration tries to evaluate the * statement and if its variable, tries to evaluate its initializer, * into its corresponding type. + * If it's an expression, tries to evaluate the expression. */ CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C); @@ -5978,7 +5966,8 @@ CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E); * Returns the evaluation result as an unsigned integer if * the kind is Int and clang_EvalResult_isUnsignedInt is non-zero. */ -CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E); +CINDEX_LINKAGE unsigned long long +clang_EvalResult_getAsUnsigned(CXEvalResult E); /** * Returns the evaluation result as double if the @@ -5992,7 +5981,7 @@ CINDEX_LINKAGE double clang_EvalResult_getAsDouble(CXEvalResult E); * instead call clang_EvalResult_dispose on the CXEvalResult returned * by clang_Cursor_Evaluate. */ -CINDEX_LINKAGE const char* clang_EvalResult_getAsStr(CXEvalResult E); +CINDEX_LINKAGE const char *clang_EvalResult_getAsStr(CXEvalResult E); /** * Disposes the created Eval memory. @@ -6050,7 +6039,8 @@ CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); * is associated with. */ CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index, - CXString *original, CXString *transformed); + CXString *original, + CXString *transformed); /** * Dispose the remapping. @@ -6066,10 +6056,7 @@ CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); * @{ */ -enum CXVisitorResult { - CXVisit_Break, - CXVisit_Continue -}; +enum CXVisitorResult { CXVisit_Break, CXVisit_Continue }; typedef struct CXCursorAndRangeVisitor { void *context; @@ -6107,8 +6094,8 @@ typedef enum { * * \returns one of the CXResult enumerators. */ -CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file, - CXCursorAndRangeVisitor visitor); +CINDEX_LINKAGE CXResult clang_findReferencesInFile( + CXCursor cursor, CXFile file, CXCursorAndRangeVisitor visitor); /** * Find #import/#include directives in a specific file. @@ -6122,15 +6109,14 @@ CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file, * * \returns one of the CXResult enumerators. */ -CINDEX_LINKAGE CXResult clang_findIncludesInFile(CXTranslationUnit TU, - CXFile file, - CXCursorAndRangeVisitor visitor); +CINDEX_LINKAGE CXResult clang_findIncludesInFile( + CXTranslationUnit TU, CXFile file, CXCursorAndRangeVisitor visitor); #ifdef __has_feature -# if __has_feature(blocks) +#if __has_feature(blocks) -typedef enum CXVisitorResult - (^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange); +typedef enum CXVisitorResult (^CXCursorAndRangeVisitorBlock)(CXCursor, + CXSourceRange); CINDEX_LINKAGE CXResult clang_findReferencesInFileWithBlock(CXCursor, CXFile, @@ -6140,7 +6126,7 @@ CINDEX_LINKAGE CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile, CXCursorAndRangeVisitorBlock); -# endif +#endif #endif /** @@ -6223,46 +6209,46 @@ typedef struct { } CXIdxImportedASTFileInfo; typedef enum { - CXIdxEntity_Unexposed = 0, - CXIdxEntity_Typedef = 1, - CXIdxEntity_Function = 2, - CXIdxEntity_Variable = 3, - CXIdxEntity_Field = 4, - CXIdxEntity_EnumConstant = 5, + CXIdxEntity_Unexposed = 0, + CXIdxEntity_Typedef = 1, + CXIdxEntity_Function = 2, + CXIdxEntity_Variable = 3, + CXIdxEntity_Field = 4, + CXIdxEntity_EnumConstant = 5, - CXIdxEntity_ObjCClass = 6, - CXIdxEntity_ObjCProtocol = 7, - CXIdxEntity_ObjCCategory = 8, + CXIdxEntity_ObjCClass = 6, + CXIdxEntity_ObjCProtocol = 7, + CXIdxEntity_ObjCCategory = 8, CXIdxEntity_ObjCInstanceMethod = 9, - CXIdxEntity_ObjCClassMethod = 10, - CXIdxEntity_ObjCProperty = 11, - CXIdxEntity_ObjCIvar = 12, - - CXIdxEntity_Enum = 13, - CXIdxEntity_Struct = 14, - CXIdxEntity_Union = 15, - - CXIdxEntity_CXXClass = 16, - CXIdxEntity_CXXNamespace = 17, - CXIdxEntity_CXXNamespaceAlias = 18, - CXIdxEntity_CXXStaticVariable = 19, - CXIdxEntity_CXXStaticMethod = 20, - CXIdxEntity_CXXInstanceMethod = 21, - CXIdxEntity_CXXConstructor = 22, - CXIdxEntity_CXXDestructor = 23, + CXIdxEntity_ObjCClassMethod = 10, + CXIdxEntity_ObjCProperty = 11, + CXIdxEntity_ObjCIvar = 12, + + CXIdxEntity_Enum = 13, + CXIdxEntity_Struct = 14, + CXIdxEntity_Union = 15, + + CXIdxEntity_CXXClass = 16, + CXIdxEntity_CXXNamespace = 17, + CXIdxEntity_CXXNamespaceAlias = 18, + CXIdxEntity_CXXStaticVariable = 19, + CXIdxEntity_CXXStaticMethod = 20, + CXIdxEntity_CXXInstanceMethod = 21, + CXIdxEntity_CXXConstructor = 22, + CXIdxEntity_CXXDestructor = 23, CXIdxEntity_CXXConversionFunction = 24, - CXIdxEntity_CXXTypeAlias = 25, - CXIdxEntity_CXXInterface = 26 + CXIdxEntity_CXXTypeAlias = 25, + CXIdxEntity_CXXInterface = 26 } CXIdxEntityKind; typedef enum { CXIdxEntityLang_None = 0, - CXIdxEntityLang_C = 1, + CXIdxEntityLang_C = 1, CXIdxEntityLang_ObjC = 2, - CXIdxEntityLang_CXX = 3, - CXIdxEntityLang_Swift = 4 + CXIdxEntityLang_CXX = 3, + CXIdxEntityLang_Swift = 4 } CXIdxEntityLanguage; /** @@ -6276,16 +6262,16 @@ typedef enum { * CXIdxEntity_CXXTypeAlias */ typedef enum { - CXIdxEntity_NonTemplate = 0, - CXIdxEntity_Template = 1, + CXIdxEntity_NonTemplate = 0, + CXIdxEntity_Template = 1, CXIdxEntity_TemplatePartialSpecialization = 2, CXIdxEntity_TemplateSpecialization = 3 } CXIdxEntityCXXTemplateKind; typedef enum { - CXIdxAttr_Unexposed = 0, - CXIdxAttr_IBAction = 1, - CXIdxAttr_IBOutlet = 2, + CXIdxAttr_Unexposed = 0, + CXIdxAttr_IBAction = 1, + CXIdxAttr_IBOutlet = 2, CXIdxAttr_IBOutletCollection = 3 } CXIdxAttrKind; @@ -6317,9 +6303,7 @@ typedef struct { CXIdxLoc classLoc; } CXIdxIBOutletCollectionAttrInfo; -typedef enum { - CXIdxDeclFlag_Skipped = 0x1 -} CXIdxDeclInfoFlags; +typedef enum { CXIdxDeclFlag_Skipped = 0x1 } CXIdxDeclInfoFlags; typedef struct { const CXIdxEntityInfo *entityInfo; @@ -6488,11 +6472,10 @@ typedef struct { /** * Called at the end of indexing; passes the complete diagnostic set. */ - void (*diagnostic)(CXClientData client_data, - CXDiagnosticSet, void *reserved); + void (*diagnostic)(CXClientData client_data, CXDiagnosticSet, void *reserved); - CXIdxClientFile (*enteredMainFile)(CXClientData client_data, - CXFile mainFile, void *reserved); + CXIdxClientFile (*enteredMainFile)(CXClientData client_data, CXFile mainFile, + void *reserved); /** * Called when a file gets \#included/\#imported. @@ -6517,8 +6500,7 @@ typedef struct { CXIdxClientContainer (*startedTranslationUnit)(CXClientData client_data, void *reserved); - void (*indexDeclaration)(CXClientData client_data, - const CXIdxDeclInfo *); + void (*indexDeclaration)(CXClientData client_data, const CXIdxDeclInfo *); /** * Called to index a reference of an entity. @@ -6562,8 +6544,8 @@ clang_index_getClientContainer(const CXIdxContainerInfo *); * For setting a custom CXIdxClientContainer attached to a * container. */ -CINDEX_LINKAGE void -clang_index_setClientContainer(const CXIdxContainerInfo *,CXIdxClientContainer); +CINDEX_LINKAGE void clang_index_setClientContainer(const CXIdxContainerInfo *, + CXIdxClientContainer); /** * For retrieving a custom CXIdxClientEntity attached to an entity. @@ -6574,8 +6556,8 @@ clang_index_getClientEntity(const CXIdxEntityInfo *); /** * For setting a custom CXIdxClientEntity attached to an entity. */ -CINDEX_LINKAGE void -clang_index_setClientEntity(const CXIdxEntityInfo *, CXIdxClientEntity); +CINDEX_LINKAGE void clang_index_setClientEntity(const CXIdxEntityInfo *, + CXIdxClientEntity); /** * An indexing action/session, to be applied to one or multiple @@ -6663,18 +6645,12 @@ typedef enum { * * The rest of the parameters are the same as #clang_parseTranslationUnit. */ -CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction, - CXClientData client_data, - IndexerCallbacks *index_callbacks, - unsigned index_callbacks_size, - unsigned index_options, - const char *source_filename, - const char * const *command_line_args, - int num_command_line_args, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - CXTranslationUnit *out_TU, - unsigned TU_options); +CINDEX_LINKAGE int clang_indexSourceFile( + CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, unsigned index_options, + const char *source_filename, const char *const *command_line_args, + int num_command_line_args, struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, CXTranslationUnit *out_TU, unsigned TU_options); /** * Same as clang_indexSourceFile but requires a full command line @@ -6704,12 +6680,9 @@ CINDEX_LINKAGE int clang_indexSourceFileFullArgv( * \returns If there is a failure from which there is no recovery, returns * non-zero, otherwise returns 0. */ -CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction, - CXClientData client_data, - IndexerCallbacks *index_callbacks, - unsigned index_callbacks_size, - unsigned index_options, - CXTranslationUnit); +CINDEX_LINKAGE int clang_indexTranslationUnit( + CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, unsigned index_options, CXTranslationUnit); /** * Retrieve the CXIdxFile, file, line, column, and offset represented by @@ -6721,8 +6694,7 @@ CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction, */ CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc, CXIdxClientFile *indexFile, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -6765,8 +6737,7 @@ typedef enum CXVisitorResult (*CXFieldVisitor)(CXCursor C, * \returns a non-zero value if the traversal was terminated * prematurely by the visitor returning \c CXFieldVisit_Break. */ -CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, - CXFieldVisitor visitor, +CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, CXFieldVisitor visitor, CXClientData client_data); /** diff --git a/gnu/llvm/clang/include/clang-c/Platform.h b/gnu/llvm/clang/include/clang-c/Platform.h index 3bb66bb0df4..67c1fff8ff7 100644 --- a/gnu/llvm/clang/include/clang-c/Platform.h +++ b/gnu/llvm/clang/include/clang-c/Platform.h @@ -18,14 +18,23 @@ LLVM_CLANG_C_EXTERN_C_BEGIN -/* MSVC DLL import/export. */ -#ifdef _MSC_VER - #ifdef _CINDEX_LIB_ - #define CINDEX_LINKAGE __declspec(dllexport) - #else - #define CINDEX_LINKAGE __declspec(dllimport) +/* Windows DLL import/export. */ +#ifndef CINDEX_NO_EXPORTS + #define CINDEX_EXPORTS +#endif +#ifdef _WIN32 + #ifdef CINDEX_EXPORTS + #ifdef _CINDEX_LIB_ + #define CINDEX_LINKAGE __declspec(dllexport) + #else + #define CINDEX_LINKAGE __declspec(dllimport) + #endif #endif -#else +#elif defined(CINDEX_EXPORTS) && defined(__GNUC__) + #define CINDEX_LINKAGE __attribute__((visibility("default"))) +#endif + +#ifndef CINDEX_LINKAGE #define CINDEX_LINKAGE #endif diff --git a/gnu/llvm/clang/include/clang/AST/APValue.h b/gnu/llvm/clang/include/clang/AST/APValue.h index 63359294ef6..cca92b5f823 100644 --- a/gnu/llvm/clang/include/clang/AST/APValue.h +++ b/gnu/llvm/clang/include/clang/AST/APValue.h @@ -372,7 +372,7 @@ public: bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } void dump() const; - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; std::string getAsString(const ASTContext &Ctx, QualType Ty) const; diff --git a/gnu/llvm/clang/include/clang/AST/ASTConcept.h b/gnu/llvm/clang/include/clang/AST/ASTConcept.h index 3ebaad4eafd..71bf14a8786 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTConcept.h +++ b/gnu/llvm/clang/include/clang/AST/ASTConcept.h @@ -193,4 +193,4 @@ public: } // clang -#endif // LLVM_CLANG_AST_ASTCONCEPT_H \ No newline at end of file +#endif // LLVM_CLANG_AST_ASTCONCEPT_H diff --git a/gnu/llvm/clang/include/clang/AST/ASTContext.h b/gnu/llvm/clang/include/clang/AST/ASTContext.h index f8403cf13c4..9020e6629d0 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTContext.h +++ b/gnu/llvm/clang/include/clang/AST/ASTContext.h @@ -15,7 +15,7 @@ #define LLVM_CLANG_AST_ASTCONTEXT_H #include "clang/AST/ASTContextAllocate.h" -#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/ASTFwd.h" #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/ComparisonCategories.h" @@ -26,7 +26,6 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RawCommentList.h" -#include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" @@ -40,7 +39,6 @@ #include "clang/Basic/SanitizerBlacklist.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/XRayLists.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" @@ -62,6 +60,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TypeSize.h" #include #include #include @@ -75,6 +74,7 @@ namespace llvm { struct fltSemantics; +template class SmallPtrSet; } // namespace llvm @@ -94,6 +94,9 @@ class CXXConstructorDecl; class CXXMethodDecl; class CXXRecordDecl; class DiagnosticsEngine; +class ParentMapContext; +class DynTypedNode; +class DynTypedNodeList; class Expr; class FixedPointSemantics; class GlobalDecl; @@ -102,6 +105,7 @@ class MangleNumberingContext; class MaterializeTemporaryExpr; class MemberSpecializationInfo; class Module; +struct MSGuidDeclParts; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCContainerDecl; @@ -114,11 +118,13 @@ class ObjCPropertyDecl; class ObjCPropertyImplDecl; class ObjCProtocolDecl; class ObjCTypeParamDecl; +class OMPTraitInfo; struct ParsedTargetAttr; class Preprocessor; class Stmt; class StoredDeclsMap; class TargetAttr; +class TargetInfo; class TemplateDecl; class TemplateParameterList; class TemplateTemplateParmDecl; @@ -136,6 +142,7 @@ class Context; } // namespace Builtin enum BuiltinTemplateKind : int; +enum OpenCLTypeKind : uint8_t; namespace comments { @@ -188,6 +195,8 @@ class ASTContext : public RefCountedBase { DependentAddressSpaceTypes; mutable llvm::FoldingSet VectorTypes; mutable llvm::FoldingSet DependentVectorTypes; + mutable llvm::FoldingSet MatrixTypes; + mutable llvm::FoldingSet DependentSizedMatrixTypes; mutable llvm::FoldingSet FunctionNoProtoTypes; mutable llvm::ContextualFoldingSet FunctionProtoTypes; @@ -218,6 +227,8 @@ class ASTContext : public RefCountedBase { mutable llvm::FoldingSet AtomicTypes; llvm::FoldingSet AttributedTypes; mutable llvm::FoldingSet PipeTypes; + mutable llvm::FoldingSet ExtIntTypes; + mutable llvm::FoldingSet DependentExtIntTypes; mutable llvm::FoldingSet QualifiedTemplateNames; mutable llvm::FoldingSet DependentTemplateNames; @@ -264,6 +275,9 @@ class ASTContext : public RefCountedBase { /// Mapping from __block VarDecls to BlockVarCopyInit. llvm::DenseMap BlockVarCopyInits; + /// Mapping from GUIDs to the corresponding MSGuidDecl. + mutable llvm::FoldingSet MSGuidDecls; + /// Used to cleanups APValues stored in the AST. mutable llvm::SmallVector APValueCleanups; @@ -565,18 +579,9 @@ private: const TargetInfo *AuxTarget = nullptr; clang::PrintingPolicy PrintingPolicy; std::unique_ptr InterpContext; - - ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs; + std::unique_ptr ParentMapCtx; public: - ast_type_traits::TraversalKind getTraversalKind() const { return Traversal; } - void setTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; } - - const Expr *traverseIgnored(const Expr *E) const; - Expr *traverseIgnored(Expr *E) const; - ast_type_traits::DynTypedNode - traverseIgnored(const ast_type_traits::DynTypedNode &N) const; - IdentifierTable &Idents; SelectorTable &Selectors; Builtin::Context &BuiltinInfo; @@ -587,46 +592,8 @@ public: /// Returns the clang bytecode interpreter context. interp::Context &getInterpContext(); - /// Container for either a single DynTypedNode or for an ArrayRef to - /// DynTypedNode. For use with ParentMap. - class DynTypedNodeList { - using DynTypedNode = ast_type_traits::DynTypedNode; - - llvm::AlignedCharArrayUnion> Storage; - bool IsSingleNode; - - public: - DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) { - new (Storage.buffer) DynTypedNode(N); - } - - DynTypedNodeList(ArrayRef A) : IsSingleNode(false) { - new (Storage.buffer) ArrayRef(A); - } - - const ast_type_traits::DynTypedNode *begin() const { - if (!IsSingleNode) - return reinterpret_cast *>(Storage.buffer) - ->begin(); - return reinterpret_cast(Storage.buffer); - } - - const ast_type_traits::DynTypedNode *end() const { - if (!IsSingleNode) - return reinterpret_cast *>(Storage.buffer) - ->end(); - return reinterpret_cast(Storage.buffer) + 1; - } - - size_t size() const { return end() - begin(); } - bool empty() const { return begin() == end(); } - - const DynTypedNode &operator[](size_t N) const { - assert(N < size() && "Out of bounds!"); - return *(begin() + N); - } - }; + /// Returns the dynamic AST node parent map context. + ParentMapContext &getParentMapContext(); // A traversal scope limits the parts of the AST visible to certain analyses. // RecursiveASTVisitor::TraverseAST will only visit reachable nodes, and @@ -638,35 +605,9 @@ public: std::vector getTraversalScope() const { return TraversalScope; } void setTraversalScope(const std::vector &); - /// Returns the parents of the given node (within the traversal scope). - /// - /// Note that this will lazily compute the parents of all nodes - /// and store them for later retrieval. Thus, the first call is O(n) - /// in the number of AST nodes. - /// - /// Caveats and FIXMEs: - /// Calculating the parent map over all AST nodes will need to load the - /// full AST. This can be undesirable in the case where the full AST is - /// expensive to create (for example, when using precompiled header - /// preambles). Thus, there are good opportunities for optimization here. - /// One idea is to walk the given node downwards, looking for references - /// to declaration contexts - once a declaration context is found, compute - /// the parent map for the declaration context; if that can satisfy the - /// request, loading the whole AST can be avoided. Note that this is made - /// more complex by statements in templates having multiple parents - those - /// problems can be solved by building closure over the templated parts of - /// the AST, which also avoids touching large parts of the AST. - /// Additionally, we will want to add an interface to already give a hint - /// where to search for the parents, for example when looking at a statement - /// inside a certain function. - /// - /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, - /// NestedNameSpecifier or NestedNameSpecifierLoc. - template DynTypedNodeList getParents(const NodeT &Node) { - return getParents(ast_type_traits::DynTypedNode::create(Node)); - } - - DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node); + /// Forwards to get node parents from the ParentMapContext. New callers should + /// use ParentMapContext::getParents() directly. + template DynTypedNodeList getParents(const NodeT &Node); const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; @@ -717,7 +658,7 @@ public: /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. - QualType getRealTypeForBitwidth(unsigned DestWidth) const; + QualType getRealTypeForBitwidth(unsigned DestWidth, bool ExplicitIEEE) const; bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; @@ -791,15 +732,7 @@ public: RawComment *getRawCommentForDeclNoCache(const Decl *D) const; public: - RawCommentList &getRawCommentList() { - return Comments; - } - - void addComment(const RawComment &RC) { - assert(LangOpts.RetainCommentsFromSystemHeaders || - !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin())); - Comments.addComment(RC, LangOpts.CommentOpts, BumpAlloc); - } + void addComment(const RawComment &RC); /// Return the documentation comment attached to a given declaration. /// Returns nullptr if no comment is attached. @@ -959,7 +892,7 @@ public: void addedLocalImportDecl(ImportDecl *Import); static ImportDecl *getNextLocalImport(ImportDecl *Import) { - return Import->NextLocalImport; + return Import->getNextLocalImport(); } using import_range = llvm::iterator_range; @@ -987,13 +920,7 @@ public: /// Get the additional modules in which the definition \p Def has /// been merged. - ArrayRef getModulesWithMergedDefinition(const NamedDecl *Def) { - auto MergedIt = - MergedDefModules.find(cast(Def->getCanonicalDecl())); - if (MergedIt == MergedDefModules.end()) - return None; - return MergedIt->second; - } + ArrayRef getModulesWithMergedDefinition(const NamedDecl *Def); /// Add a declaration to the list of declarations that are initialized /// for a module. This will typically be a global variable (with internal @@ -1038,6 +965,7 @@ public: CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy, SatUnsignedLongFractTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON + CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType Float128ComplexTy; @@ -1052,7 +980,8 @@ public: #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; - CanQualType OMPArraySectionTy; + CanQualType IncompleteMatrixIdxTy; + CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" @@ -1066,7 +995,10 @@ public: // Decl used to help define __builtin_va_list for some targets. // The decl is built when constructing 'BuiltinVaListDecl'. - mutable Decl *VaListTagDecl; + mutable Decl *VaListTagDecl = nullptr; + + // Implicitly-declared type 'struct _GUID'. + mutable TagDecl *MSGuidTagDecl = nullptr; ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins); @@ -1278,12 +1210,20 @@ public: /// Return a write_only pipe type for the specified type. QualType getWritePipeType(QualType T) const; + /// Return an extended integer type with the specified signedness and bit + /// count. + QualType getExtIntType(bool Unsigned, unsigned NumBits) const; + + /// Return a dependent extended integer type with the specified signedness and + /// bit count. + QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const; + /// Gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; /// Map an AST Type to an OpenCLTypeKind enum value. - TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const; + OpenCLTypeKind getOpenCLTypeKind(const Type *T) const; /// Get address space for OpenCL type. LangAS getOpenCLTypeAddrSpace(const Type *T) const; @@ -1358,6 +1298,27 @@ public: /// Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; + // Convenience struct to return information about a builtin vector type. + struct BuiltinVectorTypeInfo { + QualType ElementType; + llvm::ElementCount EC; + unsigned NumVectors; + BuiltinVectorTypeInfo(QualType ElementType, llvm::ElementCount EC, + unsigned NumVectors) + : ElementType(ElementType), EC(EC), NumVectors(NumVectors) {} + }; + + /// Returns the element type, element count and number of vectors + /// (in case of tuple) for a builtin vector type. + BuiltinVectorTypeInfo + getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const; + + /// Return the unique reference to a scalable vector type of the specified + /// element type and scalable number of elements. + /// + /// \pre \p EltTy must be a built-in type. + QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const; + /// Return the unique reference to a vector type of the specified /// element type and size. /// @@ -1385,6 +1346,20 @@ public: Expr *SizeExpr, SourceLocation AttrLoc) const; + /// Return the unique reference to the matrix type of the specified element + /// type and size + /// + /// \pre \p ElementType must be a valid matrix element type (see + /// MatrixType::isValidElementType). + QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, + unsigned NumColumns) const; + + /// Return the unique reference to the matrix type of the specified element + /// type and size + QualType getDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, + Expr *ColumnExpr, + SourceLocation AttrLoc) const; + QualType getDependentAddressSpaceType(QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttrLoc) const; @@ -1518,6 +1493,8 @@ public: QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl, ArrayRef protocols) const; + void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, + ObjCTypeParamDecl *New) const; bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); @@ -1713,23 +1690,9 @@ public: return NSCopyingName; } - CanQualType getNSUIntegerType() const { - assert(Target && "Expected target to be initialized"); - const llvm::Triple &T = Target->getTriple(); - // Windows is LLP64 rather than LP64 - if (T.isOSWindows() && T.isArch64Bit()) - return UnsignedLongLongTy; - return UnsignedLongTy; - } + CanQualType getNSUIntegerType() const; - CanQualType getNSIntegerType() const { - assert(Target && "Expected target to be initialized"); - const llvm::Triple &T = Target->getTriple(); - // Windows is LLP64 rather than LP64 - if (T.isOSWindows() && T.isArch64Bit()) - return LongLongTy; - return LongTy; - } + CanQualType getNSIntegerType() const; /// Retrieve the identifier 'bool'. IdentifierInfo *getBoolName() const { @@ -1944,6 +1907,15 @@ public: return getTypeDeclType(getBuiltinMSVaListDecl()); } + /// Retrieve the implicitly-predeclared 'struct _GUID' declaration. + TagDecl *getMSGuidTagDecl() const { return MSGuidTagDecl; } + + /// Retrieve the implicitly-predeclared 'struct _GUID' type. + QualType getMSGuidType() const { + assert(MSGuidTagDecl && "asked for GUID type but MS extensions disabled"); + return getTagDeclType(MSGuidTagDecl); + } + /// Return whether a declaration to a builtin is allowed to be /// overloaded/redeclared. bool canBuiltinBeRedeclared(const FunctionDecl *) const; @@ -2207,9 +2179,7 @@ public: /// Return the alignment (in bytes) of the thrown exception object. This is /// only meaningful for targets that allocate C++ exceptions in a system /// runtime, such as those using the Itanium C++ ABI. - CharUnits getExnObjectAlignment() const { - return toCharUnitsFromBits(Target->getExnObjectAlignment()); - } + CharUnits getExnObjectAlignment() const; /// Get or compute information about the layout of the specified /// record (struct/union/class) \p D, which indicates its size and field @@ -2627,7 +2597,7 @@ public: QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false, bool BlockReturnType = false); QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, - bool Unqualified = false); + bool Unqualified = false, bool AllowCXX = false); QualType mergeFunctionParameterTypes(QualType, QualType, bool OfBlockPointer = false, bool Unqualified = false); @@ -2848,6 +2818,10 @@ public: /// PredefinedExpr to cache evaluated results. StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const; + /// Return a declaration for the global GUID object representing the given + /// GUID value. + MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const; + /// Parses the target attributes passed in, and returns only the ones that are /// valid feature names. ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const; @@ -3026,8 +3000,6 @@ private: llvm::PointerIntPair LastSDM; std::vector TraversalScope; - class ParentMap; - std::map> Parents; std::unique_ptr VTContext; @@ -3040,6 +3012,7 @@ public: PSF_Write = 0x2, PSF_Execute = 0x4, PSF_Implicit = 0x8, + PSF_ZeroInit = 0x10, PSF_Invalid = 0x80000000U, }; @@ -3057,8 +3030,20 @@ public: }; llvm::StringMap SectionInfos; + + /// Return a new OMPTraitInfo object owned by this context. + OMPTraitInfo &getNewOMPTraitInfo(); + +private: + /// All OMPTraitInfo objects live in this collection, one per + /// `pragma omp [begin] declare variant` directive. + SmallVector, 4> OMPTraitInfoVector; }; +/// Insertion operator for diagnostics. +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const ASTContext::SectionInfo &Section); + /// Utility function for constructing a nullary selector. inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); @@ -3071,22 +3056,6 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) { return Ctx.Selectors.getSelector(1, &II); } -class TraversalKindScope { - ASTContext &Ctx; - ast_type_traits::TraversalKind TK = ast_type_traits::TK_AsIs; - -public: - TraversalKindScope(ASTContext &Ctx, - llvm::Optional ScopeTK) - : Ctx(Ctx) { - TK = Ctx.getTraversalKind(); - if (ScopeTK) - Ctx.setTraversalKind(*ScopeTK); - } - - ~TraversalKindScope() { Ctx.setTraversalKind(TK); } -}; - } // namespace clang // operator new and delete aren't allowed inside namespaces. diff --git a/gnu/llvm/clang/include/clang/AST/ASTDumper.h b/gnu/llvm/clang/include/clang/AST/ASTDumper.h index 61202f057a8..a154bc2db3a 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTDumper.h +++ b/gnu/llvm/clang/include/clang/AST/ASTDumper.h @@ -11,6 +11,7 @@ #include "clang/AST/ASTNodeTraverser.h" #include "clang/AST/TextNodeDumper.h" +#include "clang/Basic/SourceManager.h" namespace clang { @@ -23,18 +24,11 @@ class ASTDumper : public ASTNodeTraverser { const bool ShowColors; public: - ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, - const SourceManager *SM) - : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {} - - ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, - const SourceManager *SM, bool ShowColors) - : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} - ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, - const SourceManager *SM, bool ShowColors, - const PrintingPolicy &PrintPolicy) - : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), - ShowColors(ShowColors) {} + ASTDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors) + : NodeDumper(OS, Context, ShowColors), OS(OS), ShowColors(ShowColors) {} + + ASTDumper(raw_ostream &OS, bool ShowColors) + : NodeDumper(OS, ShowColors), OS(OS), ShowColors(ShowColors) {} TextNodeDumper &doGetNodeDelegate() { return NodeDumper; } diff --git a/gnu/llvm/clang/include/clang/AST/ASTDumperUtils.h b/gnu/llvm/clang/include/clang/AST/ASTDumperUtils.h index 55a085449a9..1dce913049a 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTDumperUtils.h +++ b/gnu/llvm/clang/include/clang/AST/ASTDumperUtils.h @@ -62,6 +62,8 @@ static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false}; static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false}; // bitfield/objcproperty/objcsubscript/vectorcomponent static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false}; +// contains-errors +static const TerminalColor ErrorsColor = {llvm::raw_ostream::RED, true}; // Null statements static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false}; diff --git a/gnu/llvm/clang/include/clang/AST/ASTFwd.h b/gnu/llvm/clang/include/clang/AST/ASTFwd.h index 5a891817b33..65319a19728 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTFwd.h +++ b/gnu/llvm/clang/include/clang/AST/ASTFwd.h @@ -27,8 +27,8 @@ class Type; #include "clang/AST/TypeNodes.inc" class CXXCtorInitializer; class OMPClause; -#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME; -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } // end namespace clang diff --git a/gnu/llvm/clang/include/clang/AST/ASTImporter.h b/gnu/llvm/clang/include/clang/AST/ASTImporter.h index 490b34bf95e..205d7ec6775 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTImporter.h +++ b/gnu/llvm/clang/include/clang/AST/ASTImporter.h @@ -16,6 +16,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -349,6 +350,10 @@ class TypeSourceInfo; return ToOrErr.takeError(); } + /// Import cleanup objects owned by ExprWithCleanup. + llvm::Expected + Import(ExprWithCleanups::CleanupObject From); + /// Import the given type from the "from" context into the "to" /// context. A null type is imported as a null type (no error). /// diff --git a/gnu/llvm/clang/include/clang/AST/ASTNodeTraverser.h b/gnu/llvm/clang/include/clang/AST/ASTNodeTraverser.h index 9ebf64a12af..26656b7162b 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTNodeTraverser.h +++ b/gnu/llvm/clang/include/clang/AST/ASTNodeTraverser.h @@ -15,16 +15,20 @@ #ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H #define LLVM_CLANG_AST_ASTNODETRAVERSER_H +#include "clang/AST/ASTTypeTraits.h" #include "clang/AST/AttrVisitor.h" #include "clang/AST/CommentVisitor.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeVisitor.h" namespace clang { +class APValue; + /** ASTNodeTraverser traverses the Clang AST for dumping purposes. @@ -49,6 +53,7 @@ struct { void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); }; */ template @@ -65,8 +70,7 @@ class ASTNodeTraverser /// not already been loaded. bool Deserialize = false; - ast_type_traits::TraversalKind Traversal = - ast_type_traits::TraversalKind::TK_AsIs; + TraversalKind Traversal = TraversalKind::TK_AsIs; NodeDelegateType &getNodeDelegate() { return getDerived().doGetNodeDelegate(); @@ -77,7 +81,7 @@ public: void setDeserialize(bool D) { Deserialize = D; } bool getDeserialize() const { return Deserialize; } - void SetTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; } + void SetTraversalKind(TraversalKind TK) { Traversal = TK; } void Visit(const Decl *D) { getNodeDelegate().AddChild([=] { @@ -108,12 +112,12 @@ public: if (auto *E = dyn_cast_or_null(S)) { switch (Traversal) { - case ast_type_traits::TK_AsIs: + case TK_AsIs: break; - case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses: + case TK_IgnoreImplicitCastsAndParentheses: S = E->IgnoreParenImpCasts(); break; - case ast_type_traits::TK_IgnoreUnlessSpelledInSource: + case TK_IgnoreUnlessSpelledInSource: S = E->IgnoreUnlessSpelledInSource(); break; } @@ -131,8 +135,7 @@ public: if (isa(S) || isa(S)) return; - if (isa(S) && - Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) + if (isa(S) && Traversal == TK_IgnoreUnlessSpelledInSource) return; for (const Stmt *SubStmt : S->children()) @@ -212,6 +215,10 @@ public: }); } + void Visit(const APValue &Value, QualType Ty) { + getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); }); + } + void Visit(const comments::Comment *C, const comments::FullComment *FC) { getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(C, FC); @@ -228,7 +235,7 @@ public: }); } - void Visit(const ast_type_traits::DynTypedNode &N) { + void Visit(const DynTypedNode &N) { // FIXME: Improve this with a switch or a visitor pattern. if (const auto *D = N.get()) Visit(D); @@ -353,8 +360,6 @@ public: void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { for (const auto &Arg : *T) Visit(Arg); - if (T->isTypeAlias()) - Visit(T->getAliasedType()); } void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { Visit(T->getPointeeType()); @@ -658,7 +663,7 @@ public: } void VisitLambdaExpr(const LambdaExpr *Node) { - if (Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) { + if (Traversal == TK_IgnoreUnlessSpelledInSource) { for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { const auto *C = Node->capture_begin() + I; if (!C->isExplicit()) @@ -683,6 +688,15 @@ public: Visit(A); } + void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) { + Visit(E->getParameter()); + } + void VisitSubstNonTypeTemplateParmPackExpr( + const SubstNonTypeTemplateParmPackExpr *E) { + Visit(E->getParameterPack()); + Visit(E->getArgumentPack()); + } + void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { if (const VarDecl *CatchParam = Node->getCatchParamDecl()) Visit(CatchParam); @@ -691,6 +705,11 @@ public: void VisitExpressionTemplateArgument(const TemplateArgument &TA) { Visit(TA.getAsExpr()); } + + void VisitTypeTemplateArgument(const TemplateArgument &TA) { + Visit(TA.getAsType()); + } + void VisitPackTemplateArgument(const TemplateArgument &TA) { for (const auto &TArg : TA.pack_elements()) Visit(TArg); diff --git a/gnu/llvm/clang/include/clang/AST/ASTTypeTraits.h b/gnu/llvm/clang/include/clang/AST/ASTTypeTraits.h index 1a12281d039..328b7bce6ba 100644 --- a/gnu/llvm/clang/include/clang/AST/ASTTypeTraits.h +++ b/gnu/llvm/clang/include/clang/AST/ASTTypeTraits.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_ASTTYPETRAITS_H #include "clang/AST/ASTFwd.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" @@ -33,8 +34,6 @@ namespace clang { struct PrintingPolicy; -namespace ast_type_traits { - /// Defines how we descend a level in the AST when we pass /// through expressions. enum TraversalKind { @@ -138,6 +137,7 @@ private: NKI_QualType, NKI_TypeLoc, NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc, + NKI_CXXBaseSpecifier, NKI_CXXCtorInitializer, NKI_NestedNameSpecifier, NKI_Decl, @@ -150,8 +150,8 @@ private: #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.inc" NKI_OMPClause, -#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class, +#include "llvm/Frontend/OpenMP/OMPKinds.def" NKI_NumberOfKinds }; @@ -200,14 +200,15 @@ KIND_TO_KIND_ID(Decl) KIND_TO_KIND_ID(Stmt) KIND_TO_KIND_ID(Type) KIND_TO_KIND_ID(OMPClause) +KIND_TO_KIND_ID(CXXBaseSpecifier) #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) #include "clang/AST/DeclNodes.inc" #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.inc" -#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class) +#include "llvm/Frontend/OpenMP/OMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { @@ -277,7 +278,7 @@ public: void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; /// Dumps the node to the given output stream. - void dump(llvm::raw_ostream &OS, SourceManager &SM) const; + void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; /// For nodes which represent textual entities in the source code, /// return their SourceRange. For all other nodes, return SourceRange(). @@ -465,22 +466,22 @@ private: template struct DynTypedNode::BaseConverter< - T, typename std::enable_if::value>::type> + T, std::enable_if_t::value>> : public DynCastPtrConverter {}; template struct DynTypedNode::BaseConverter< - T, typename std::enable_if::value>::type> + T, std::enable_if_t::value>> : public DynCastPtrConverter {}; template struct DynTypedNode::BaseConverter< - T, typename std::enable_if::value>::type> + T, std::enable_if_t::value>> : public DynCastPtrConverter {}; template struct DynTypedNode::BaseConverter< - T, typename std::enable_if::value>::type> + T, std::enable_if_t::value>> : public DynCastPtrConverter {}; template <> @@ -512,6 +513,10 @@ template <> struct DynTypedNode::BaseConverter< TypeLoc, void> : public ValueConverter {}; +template <> +struct DynTypedNode::BaseConverter + : public PtrConverter {}; + // The only operation we allow on unsupported types is \c get. // This allows to conveniently use \c DynTypedNode when having an arbitrary // AST node that is not supported, but prevents misuse - a user cannot create @@ -522,18 +527,29 @@ template struct DynTypedNode::BaseConverter { } }; -} // end namespace ast_type_traits +// 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 { template <> -struct DenseMapInfo - : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {}; +struct DenseMapInfo : clang::ASTNodeKind::DenseMapInfo {}; template <> -struct DenseMapInfo - : clang::ast_type_traits::DynTypedNode::DenseMapInfo {}; +struct DenseMapInfo : clang::DynTypedNode::DenseMapInfo {}; } // end namespace llvm diff --git a/gnu/llvm/clang/include/clang/AST/Attr.h b/gnu/llvm/clang/include/clang/AST/Attr.h index bbaa46363d9..1b457337d65 100644 --- a/gnu/llvm/clang/include/clang/AST/Attr.h +++ b/gnu/llvm/clang/include/clang/AST/Attr.h @@ -13,13 +13,13 @@ #ifndef LLVM_CLANG_AST_ATTR_H #define LLVM_CLANG_AST_ATTR_H -#include "clang/AST/ASTContextAllocate.h" // For Attrs.inc +#include "clang/AST/ASTFwd.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/AttributeCommonInfo.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" @@ -40,6 +40,7 @@ class Expr; class QualType; class FunctionDecl; class TypeSourceInfo; +class OMPTraitInfo; /// Attr - This represents one attribute. class Attr : public AttributeCommonInfo { diff --git a/gnu/llvm/clang/include/clang/AST/BuiltinTypes.def b/gnu/llvm/clang/include/clang/AST/BuiltinTypes.def index 74a45ee4ccc..039765dfdfe 100644 --- a/gnu/llvm/clang/include/clang/AST/BuiltinTypes.def +++ b/gnu/llvm/clang/include/clang/AST/BuiltinTypes.def @@ -212,6 +212,9 @@ FLOATING_TYPE(LongDouble, LongDoubleTy) // '_Float16' FLOATING_TYPE(Float16, HalfTy) +// '__bf16' +FLOATING_TYPE(BFloat16, BFloat16Ty) + // '__float128' FLOATING_TYPE(Float128, Float128Ty) @@ -310,11 +313,20 @@ PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy) // context. PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) +// A placeholder type for incomplete matrix index expressions. +PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy) + // A placeholder type for OpenMP array sections. PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) +// A placeholder type for OpenMP array shaping operation. +PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) + +// A placeholder type for OpenMP iterators. +PLACEHOLDER_TYPE(OMPIterator, OMPIteratorTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(OMPArraySection) +LAST_BUILTIN_TYPE(OMPIterator) #undef LAST_BUILTIN_TYPE #endif diff --git a/gnu/llvm/clang/include/clang/AST/CXXInheritance.h b/gnu/llvm/clang/include/clang/AST/CXXInheritance.h index f223c1f2f4f..8b1bcb367b3 100644 --- a/gnu/llvm/clang/include/clang/AST/CXXInheritance.h +++ b/gnu/llvm/clang/include/clang/AST/CXXInheritance.h @@ -119,7 +119,7 @@ class CXXBasePaths { friend class CXXRecordDecl; /// The type from which this search originated. - CXXRecordDecl *Origin = nullptr; + const CXXRecordDecl *Origin = nullptr; /// Paths - The actual set of paths that can be taken from the /// derived class to the same base class. @@ -225,8 +225,8 @@ public: /// Retrieve the type from which this base-paths search /// began - CXXRecordDecl *getOrigin() const { return Origin; } - void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; } + const CXXRecordDecl *getOrigin() const { return Origin; } + void setOrigin(const CXXRecordDecl *Rec) { Origin = Rec; } /// Clear the base-paths results. void clear(); diff --git a/gnu/llvm/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/gnu/llvm/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index bd4d8247aec..33e65f8ebf4 100644 --- a/gnu/llvm/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/gnu/llvm/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -140,6 +140,7 @@ FIELD(HasInheritedAssignment, 1, NO_MERGE) /// @{ FIELD(NeedOverloadResolutionForCopyConstructor, 1, NO_MERGE) FIELD(NeedOverloadResolutionForMoveConstructor, 1, NO_MERGE) +FIELD(NeedOverloadResolutionForCopyAssignment, 1, NO_MERGE) FIELD(NeedOverloadResolutionForMoveAssignment, 1, NO_MERGE) FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE) /// @} @@ -149,6 +150,7 @@ FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE) /// @{ FIELD(DefaultedCopyConstructorIsDeleted, 1, NO_MERGE) FIELD(DefaultedMoveConstructorIsDeleted, 1, NO_MERGE) +FIELD(DefaultedCopyAssignmentIsDeleted, 1, NO_MERGE) FIELD(DefaultedMoveAssignmentIsDeleted, 1, NO_MERGE) FIELD(DefaultedDestructorIsDeleted, 1, NO_MERGE) /// @} diff --git a/gnu/llvm/clang/include/clang/AST/CanonicalType.h b/gnu/llvm/clang/include/clang/AST/CanonicalType.h index 2e00d344533..488284713bc 100644 --- a/gnu/llvm/clang/include/clang/AST/CanonicalType.h +++ b/gnu/llvm/clang/include/clang/AST/CanonicalType.h @@ -74,7 +74,7 @@ public: /// canonical type pointers. template CanQual(const CanQual &Other, - typename std::enable_if::value, int>::type = 0); + std::enable_if_t::value, int> = 0); /// Retrieve the underlying type pointer, which refers to a /// canonical type. @@ -264,6 +264,8 @@ public: // Type predicates LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) @@ -384,7 +386,7 @@ struct PointerLikeTypeTraits> { } // qualifier information is encoded in the low bits. - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm diff --git a/gnu/llvm/clang/include/clang/AST/Comment.h b/gnu/llvm/clang/include/clang/AST/Comment.h index cd9c1ce2bce..54a4b0a9cfe 100644 --- a/gnu/llvm/clang/include/clang/AST/Comment.h +++ b/gnu/llvm/clang/include/clang/AST/Comment.h @@ -209,9 +209,7 @@ public: void dump() const; void dumpColor() const; - void dump(const ASTContext &Context) const; - void dump(raw_ostream &OS, const CommandTraits *Traits, - const SourceManager *SM) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; SourceRange getSourceRange() const LLVM_READONLY { return Range; } diff --git a/gnu/llvm/clang/include/clang/AST/CommentCommands.td b/gnu/llvm/clang/include/clang/AST/CommentCommands.td index d387df7ce57..fbbfc9f7e0b 100644 --- a/gnu/llvm/clang/include/clang/AST/CommentCommands.td +++ b/gnu/llvm/clang/include/clang/AST/CommentCommands.td @@ -87,6 +87,7 @@ def P : InlineCommand<"p">; def A : InlineCommand<"a">; def E : InlineCommand<"e">; def Em : InlineCommand<"em">; +def Ref : InlineCommand<"ref">; def Anchor : InlineCommand<"anchor">; //===----------------------------------------------------------------------===// @@ -205,7 +206,6 @@ def Paragraph : VerbatimLineCommand<"paragraph">; def Mainpage : VerbatimLineCommand<"mainpage">; def Subpage : VerbatimLineCommand<"subpage">; -def Ref : VerbatimLineCommand<"ref">; def Relates : VerbatimLineCommand<"relates">; def Related : VerbatimLineCommand<"related">; diff --git a/gnu/llvm/clang/include/clang/AST/CommentSema.h b/gnu/llvm/clang/include/clang/AST/CommentSema.h index 307618fa536..6dfe0f4920d 100644 --- a/gnu/llvm/clang/include/clang/AST/CommentSema.h +++ b/gnu/llvm/clang/include/clang/AST/CommentSema.h @@ -217,6 +217,9 @@ public: bool isTemplateOrSpecialization(); bool isRecordLikeDecl(); bool isClassOrStructDecl(); + /// \return \c true if the declaration that this comment is attached to + /// declares either struct, class or tag typedef. + bool isClassOrStructOrTagTypedefDecl(); bool isUnionDecl(); bool isObjCInterfaceDecl(); bool isObjCProtocolDecl(); diff --git a/gnu/llvm/clang/include/clang/AST/ComputeDependence.h b/gnu/llvm/clang/include/clang/AST/ComputeDependence.h new file mode 100644 index 00000000000..ac2daf9eb95 --- /dev/null +++ b/gnu/llvm/clang/include/clang/AST/ComputeDependence.h @@ -0,0 +1,194 @@ +//===--- ComputeDependence.h -------------------------------------- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Calculate various template dependency flags for the AST. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H +#define LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H + +#include "clang/AST/DependenceFlags.h" +#include "clang/Basic/ExceptionSpecificationType.h" +#include "llvm/ADT/ArrayRef.h" + +namespace clang { + +class ASTContext; + +class Expr; +class FullExpr; +class OpaqueValueExpr; +class ParenExpr; +class UnaryOperator; +class UnaryExprOrTypeTraitExpr; +class ArraySubscriptExpr; +class MatrixSubscriptExpr; +class CompoundLiteralExpr; +class CastExpr; +class BinaryOperator; +class ConditionalOperator; +class BinaryConditionalOperator; +class StmtExpr; +class ConvertVectorExpr; +class VAArgExpr; +class ChooseExpr; +class NoInitExpr; +class ArrayInitLoopExpr; +class ImplicitValueInitExpr; +class InitListExpr; +class ExtVectorElementExpr; +class BlockExpr; +class AsTypeExpr; +class DeclRefExpr; +class RecoveryExpr; +class CXXRewrittenBinaryOperator; +class CXXStdInitializerListExpr; +class CXXTypeidExpr; +class MSPropertyRefExpr; +class MSPropertySubscriptExpr; +class CXXUuidofExpr; +class CXXThisExpr; +class CXXThrowExpr; +class CXXBindTemporaryExpr; +class CXXScalarValueInitExpr; +class CXXDeleteExpr; +class ArrayTypeTraitExpr; +class ExpressionTraitExpr; +class CXXNoexceptExpr; +class PackExpansionExpr; +class SubstNonTypeTemplateParmExpr; +class CoroutineSuspendExpr; +class DependentCoawaitExpr; +class CXXNewExpr; +class CXXPseudoDestructorExpr; +class OverloadExpr; +class DependentScopeDeclRefExpr; +class CXXConstructExpr; +class LambdaExpr; +class CXXUnresolvedConstructExpr; +class CXXDependentScopeMemberExpr; +class MaterializeTemporaryExpr; +class CXXFoldExpr; +class TypeTraitExpr; +class ConceptSpecializationExpr; +class PredefinedExpr; +class CallExpr; +class OffsetOfExpr; +class MemberExpr; +class ShuffleVectorExpr; +class GenericSelectionExpr; +class DesignatedInitExpr; +class ParenListExpr; +class PseudoObjectExpr; +class AtomicExpr; +class OMPArraySectionExpr; +class OMPArrayShapingExpr; +class OMPIteratorExpr; +class ObjCArrayLiteral; +class ObjCDictionaryLiteral; +class ObjCBoxedExpr; +class ObjCEncodeExpr; +class ObjCIvarRefExpr; +class ObjCPropertyRefExpr; +class ObjCSubscriptRefExpr; +class ObjCIsaExpr; +class ObjCIndirectCopyRestoreExpr; +class ObjCMessageExpr; + +// The following functions are called from constructors of `Expr`, so they +// should not access anything beyond basic +ExprDependence computeDependence(FullExpr *E); +ExprDependence computeDependence(OpaqueValueExpr *E); +ExprDependence computeDependence(ParenExpr *E); +ExprDependence computeDependence(UnaryOperator *E); +ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E); +ExprDependence computeDependence(ArraySubscriptExpr *E); +ExprDependence computeDependence(MatrixSubscriptExpr *E); +ExprDependence computeDependence(CompoundLiteralExpr *E); +ExprDependence computeDependence(CastExpr *E); +ExprDependence computeDependence(BinaryOperator *E); +ExprDependence computeDependence(ConditionalOperator *E); +ExprDependence computeDependence(BinaryConditionalOperator *E); +ExprDependence computeDependence(StmtExpr *E, unsigned TemplateDepth); +ExprDependence computeDependence(ConvertVectorExpr *E); +ExprDependence computeDependence(VAArgExpr *E); +ExprDependence computeDependence(ChooseExpr *E); +ExprDependence computeDependence(NoInitExpr *E); +ExprDependence computeDependence(ArrayInitLoopExpr *E); +ExprDependence computeDependence(ImplicitValueInitExpr *E); +ExprDependence computeDependence(InitListExpr *E); +ExprDependence computeDependence(ExtVectorElementExpr *E); +ExprDependence computeDependence(BlockExpr *E); +ExprDependence computeDependence(AsTypeExpr *E); +ExprDependence computeDependence(DeclRefExpr *E, const ASTContext &Ctx); +ExprDependence computeDependence(RecoveryExpr *E); +ExprDependence computeDependence(CXXRewrittenBinaryOperator *E); +ExprDependence computeDependence(CXXStdInitializerListExpr *E); +ExprDependence computeDependence(CXXTypeidExpr *E); +ExprDependence computeDependence(MSPropertyRefExpr *E); +ExprDependence computeDependence(MSPropertySubscriptExpr *E); +ExprDependence computeDependence(CXXUuidofExpr *E); +ExprDependence computeDependence(CXXThisExpr *E); +ExprDependence computeDependence(CXXThrowExpr *E); +ExprDependence computeDependence(CXXBindTemporaryExpr *E); +ExprDependence computeDependence(CXXScalarValueInitExpr *E); +ExprDependence computeDependence(CXXDeleteExpr *E); +ExprDependence computeDependence(ArrayTypeTraitExpr *E); +ExprDependence computeDependence(ExpressionTraitExpr *E); +ExprDependence computeDependence(CXXNoexceptExpr *E, CanThrowResult CT); +ExprDependence computeDependence(PackExpansionExpr *E); +ExprDependence computeDependence(SubstNonTypeTemplateParmExpr *E); +ExprDependence computeDependence(CoroutineSuspendExpr *E); +ExprDependence computeDependence(DependentCoawaitExpr *E); +ExprDependence computeDependence(CXXNewExpr *E); +ExprDependence computeDependence(CXXPseudoDestructorExpr *E); +ExprDependence computeDependence(OverloadExpr *E, bool KnownDependent, + bool KnownInstantiationDependent, + bool KnownContainsUnexpandedParameterPack); +ExprDependence computeDependence(DependentScopeDeclRefExpr *E); +ExprDependence computeDependence(CXXConstructExpr *E); +ExprDependence computeDependence(LambdaExpr *E, + bool ContainsUnexpandedParameterPack); +ExprDependence computeDependence(CXXUnresolvedConstructExpr *E); +ExprDependence computeDependence(CXXDependentScopeMemberExpr *E); +ExprDependence computeDependence(MaterializeTemporaryExpr *E); +ExprDependence computeDependence(CXXFoldExpr *E); +ExprDependence computeDependence(TypeTraitExpr *E); +ExprDependence computeDependence(ConceptSpecializationExpr *E, + bool ValueDependent); + +ExprDependence computeDependence(PredefinedExpr *E); +ExprDependence computeDependence(CallExpr *E, llvm::ArrayRef PreArgs); +ExprDependence computeDependence(OffsetOfExpr *E); +ExprDependence computeDependence(MemberExpr *E); +ExprDependence computeDependence(ShuffleVectorExpr *E); +ExprDependence computeDependence(GenericSelectionExpr *E, + bool ContainsUnexpandedPack); +ExprDependence computeDependence(DesignatedInitExpr *E); +ExprDependence computeDependence(ParenListExpr *E); +ExprDependence computeDependence(PseudoObjectExpr *E); +ExprDependence computeDependence(AtomicExpr *E); + +ExprDependence computeDependence(OMPArraySectionExpr *E); +ExprDependence computeDependence(OMPArrayShapingExpr *E); +ExprDependence computeDependence(OMPIteratorExpr *E); + +ExprDependence computeDependence(ObjCArrayLiteral *E); +ExprDependence computeDependence(ObjCDictionaryLiteral *E); +ExprDependence computeDependence(ObjCBoxedExpr *E); +ExprDependence computeDependence(ObjCEncodeExpr *E); +ExprDependence computeDependence(ObjCIvarRefExpr *E); +ExprDependence computeDependence(ObjCPropertyRefExpr *E); +ExprDependence computeDependence(ObjCSubscriptRefExpr *E); +ExprDependence computeDependence(ObjCIsaExpr *E); +ExprDependence computeDependence(ObjCIndirectCopyRestoreExpr *E); +ExprDependence computeDependence(ObjCMessageExpr *E); + +} // namespace clang +#endif diff --git a/gnu/llvm/clang/include/clang/AST/DataCollection.h b/gnu/llvm/clang/include/clang/AST/DataCollection.h index 37f101793ec..14d1bc18862 100644 --- a/gnu/llvm/clang/include/clang/AST/DataCollection.h +++ b/gnu/llvm/clang/include/clang/AST/DataCollection.h @@ -50,10 +50,9 @@ template void addDataToConsumer(T &DataConsumer, const QualType &QT) { } template -typename std::enable_if< - std::is_integral::value || std::is_enum::value || - std::is_convertible::value // for llvm::hash_code - >::type +std::enable_if_t::value || std::is_enum::value || + std::is_convertible::value // for llvm::hash_code + > addDataToConsumer(T &DataConsumer, Type Data) { DataConsumer.update(StringRef(reinterpret_cast(&Data), sizeof(Data))); } diff --git a/gnu/llvm/clang/include/clang/AST/Decl.h b/gnu/llvm/clang/include/clang/AST/Decl.h index 43c6c7b85db..28faa2c1fc7 100644 --- a/gnu/llvm/clang/include/clang/AST/Decl.h +++ b/gnu/llvm/clang/include/clang/AST/Decl.h @@ -2030,7 +2030,7 @@ public: /// declaration to the declaration that is a definition (if there is one). bool isDefined(const FunctionDecl *&Definition) const; - virtual bool isDefined() const { + bool isDefined() const { const FunctionDecl* Definition; return isDefined(Definition); } @@ -2125,19 +2125,17 @@ public: bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; } void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; } - /// Whether this function is defaulted per C++0x. Only valid for - /// special member functions. + /// Whether this function is defaulted. Valid for e.g. + /// special member functions, defaulted comparisions (not methods!). bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; } void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; } - /// Whether this function is explicitly defaulted per C++0x. Only valid - /// for special member functions. + /// Whether this function is explicitly defaulted. bool isExplicitlyDefaulted() const { return FunctionDeclBits.IsExplicitlyDefaulted; } - /// State that this function is explicitly defaulted per C++0x. Only valid - /// for special member functions. + /// State that this function is explicitly defaulted. void setExplicitlyDefaulted(bool ED = true) { FunctionDeclBits.IsExplicitlyDefaulted = ED; } @@ -2306,8 +2304,13 @@ public: /// allocation function. [...] /// /// If this function is an aligned allocation/deallocation function, return - /// true through IsAligned. - bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const; + /// the parameter number of the requested alignment through AlignmentParam. + /// + /// If this function is an allocation/deallocation function that takes + /// the `std::nothrow_t` tag, return true through IsNothrow, + bool isReplaceableGlobalAllocationFunction( + Optional *AlignmentParam = nullptr, + bool *IsNothrow = nullptr) const; /// Determine if this function provides an inline implementation of a builtin. bool isInlineBuiltinDeclaration() const; @@ -2436,6 +2439,14 @@ public: /// parameters have default arguments (in C++). unsigned getMinRequiredArguments() const; + /// Determine whether this function has a single parameter, or multiple + /// parameters where all but the first have default arguments. + /// + /// This notion is used in the definition of copy/move constructors and + /// initializer list constructors. Note that, unlike getMinRequiredArguments, + /// parameter packs are not treated specially here. + bool hasOneParamOrDefaultArgs() const; + /// Find the source location information for how the type of this function /// was written. May be absent (for example if the function was declared via /// a typedef) and may contain a different type from that of the function @@ -2607,7 +2618,13 @@ public: /// Retrieve the function declaration from which this function could /// be instantiated, if it is an instantiation (rather than a non-template /// or a specialization, for example). - FunctionDecl *getTemplateInstantiationPattern() const; + /// + /// If \p ForDefinition is \c false, explicit specializations will be treated + /// as if they were implicit instantiations. This will then find the pattern + /// corresponding to non-definition portions of the declaration, such as + /// default arguments and the exception specification. + FunctionDecl * + getTemplateInstantiationPattern(bool ForDefinition = true) const; /// Retrieve the primary template that this function template /// specialization either specializes or was instantiated from. @@ -2915,12 +2932,15 @@ public: /// Returns the parent of this field declaration, which /// is the struct in which this field is defined. + /// + /// Returns null if this is not a normal class/struct field declaration, e.g. + /// ObjCAtDefsFieldDecl, ObjCIvarDecl. const RecordDecl *getParent() const { - return cast(getDeclContext()); + return dyn_cast(getDeclContext()); } RecordDecl *getParent() { - return cast(getDeclContext()); + return dyn_cast(getDeclContext()); } SourceRange getSourceRange() const override LLVM_READONLY; @@ -3534,6 +3554,7 @@ class EnumDecl : public TagDecl { /// negative enumerators of this enum. (see getNumNegativeBits) void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; } +public: /// True if this tag declaration is a scoped enumeration. Only /// possible in C++11 mode. void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; } @@ -3550,6 +3571,7 @@ class EnumDecl : public TagDecl { /// Microsoft-style enumeration with a fixed underlying type. void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; } +private: /// True if a valid hash is stored in ODRHash. bool hasODRHash() const { return EnumDeclBits.HasODRHash; } void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; } @@ -3954,6 +3976,11 @@ public: return cast_or_null(TagDecl::getDefinition()); } + /// Returns whether this record is a union, or contains (at any nesting level) + /// a union member. This is used by CMSE to warn about possible information + /// leaks. + bool isOrContainsUnion() const; + // Iterator access to field members. The field iterator only visits // the non-static data members of this class, ignoring any static // data members, functions, constructors, destructors, etc. @@ -4335,17 +4362,18 @@ class ImportDecl final : public Decl, friend class ASTReader; friend TrailingObjects; - /// The imported module, along with a bit that indicates whether - /// we have source-location information for each identifier in the module - /// name. - /// - /// When the bit is false, we only have a single source location for the - /// end of the import declaration. - llvm::PointerIntPair ImportedAndComplete; + /// The imported module. + Module *ImportedModule = nullptr; /// The next import in the list of imports local to the translation /// unit being parsed (not loaded from an AST file). - ImportDecl *NextLocalImport = nullptr; + /// + /// Includes a bit that indicates whether we have source-location information + /// for each identifier in the module name. + /// + /// When the bit is false, we only have a single source location for the + /// end of the import declaration. + llvm::PointerIntPair NextLocalImportAndComplete; ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef IdentifierLocs); @@ -4355,6 +4383,20 @@ class ImportDecl final : public Decl, ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {} + bool isImportComplete() const { return NextLocalImportAndComplete.getInt(); } + + void setImportComplete(bool C) { NextLocalImportAndComplete.setInt(C); } + + /// The next import in the list of imports local to the translation + /// unit being parsed (not loaded from an AST file). + ImportDecl *getNextLocalImport() const { + return NextLocalImportAndComplete.getPointer(); + } + + void setNextLocalImport(ImportDecl *Import) { + NextLocalImportAndComplete.setPointer(Import); + } + public: /// Create a new module import declaration. static ImportDecl *Create(ASTContext &C, DeclContext *DC, @@ -4372,7 +4414,7 @@ public: unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. - Module *getImportedModule() const { return ImportedAndComplete.getPointer(); } + Module *getImportedModule() const { return ImportedModule; } /// Retrieves the locations of each of the identifiers that make up /// the complete module name in the import declaration. @@ -4520,6 +4562,13 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) { return ED->isScoped(); } +/// OpenMP variants are mangled early based on their OpenMP context selector. +/// The new name looks likes this: +/// + OpenMPVariantManglingSeparatorStr + +static constexpr StringRef getOpenMPVariantManglingSeparatorStr() { + return "$ompvariant"; +} + } // namespace clang #endif // LLVM_CLANG_AST_DECL_H diff --git a/gnu/llvm/clang/include/clang/AST/DeclBase.h b/gnu/llvm/clang/include/clang/AST/DeclBase.h index fbcf255add1..4f33ff104ff 100644 --- a/gnu/llvm/clang/include/clang/AST/DeclBase.h +++ b/gnu/llvm/clang/include/clang/AST/DeclBase.h @@ -66,6 +66,7 @@ class SourceManager; class Stmt; class StoredDeclsMap; class TemplateDecl; +class TemplateParameterList; class TranslationUnitDecl; class UsingDirectiveDecl; @@ -465,6 +466,10 @@ public: ASTContext &getASTContext() const LLVM_READONLY; + /// Helper to get the language options from the ASTContext. + /// Defined out of line to avoid depending on ASTContext.h. + const LangOptions &getLangOpts() const LLVM_READONLY; + void setAccess(AccessSpecifier AS) { Access = AS; assert(AccessDeclContextSanity()); @@ -514,7 +519,7 @@ public: if (!HasAttrs) return; AttrVec &Vec = getAttrs(); - Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa), Vec.end()); + llvm::erase_if(Vec, [](Attr *A) { return isa(A); }); if (Vec.empty()) HasAttrs = false; @@ -626,7 +631,16 @@ protected: setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate); } - /// Set the owning module ID. +public: + /// Set the FromASTFile flag. This indicates that this declaration + /// was deserialized and not parsed from source code and enables + /// features such as module ownership information. + void setFromASTFile() { + FromASTFile = true; + } + + /// Set the owning module ID. This may only be called for + /// deserialized Decls. void setOwningModuleID(unsigned ID) { assert(isFromASTFile() && "Only works on a deserialized declaration"); *((unsigned*)this - 2) = ID; @@ -767,18 +781,19 @@ public: /// all declarations in a global module fragment are unowned. Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const; - /// Determine whether this declaration might be hidden from name - /// lookup. Note that the declaration might be visible even if this returns - /// \c false, if the owning module is visible within the query context. - // FIXME: Rename this to make it clearer what it does. - bool isHidden() const { - return (int)getModuleOwnershipKind() > (int)ModuleOwnershipKind::Visible; + /// Determine whether this declaration is definitely visible to name lookup, + /// independent of whether the owning module is visible. + /// Note: The declaration may be visible even if this returns \c false if the + /// owning module is visible within the query context. This is a low-level + /// helper function; most code should be calling Sema::isVisible() instead. + bool isUnconditionallyVisible() const { + return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible; } /// Set that this declaration is globally visible, even if it came from a /// module that is not visible. void setVisibleDespiteOwningModule() { - if (isHidden()) + if (!isUnconditionallyVisible()) setModuleOwnershipKind(ModuleOwnershipKind::Visible); } @@ -848,6 +863,10 @@ public: // within the scope of a template parameter). bool isTemplated() const; + /// Determine the number of levels of template parameter surrounding this + /// declaration. + unsigned getTemplateDepth() const; + /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this /// scoped decl is defined outside the current function or method. This is /// roughly global variables and functions, but also handles enums (which @@ -856,15 +875,19 @@ public: return getParentFunctionOrMethod() == nullptr; } - /// Returns true if this declaration is lexically inside a function or inside - /// a variable initializer. It recognizes non-defining declarations as well - /// as members of local classes: + /// Determine whether a substitution into this declaration would occur as + /// part of a substitution into a dependent local scope. Such a substitution + /// transitively substitutes into all constructs nested within this + /// declaration. + /// + /// This recognizes non-defining declarations as well as members of local + /// classes and lambdas: /// \code - /// void foo() { void bar(); } - /// void foo2() { class ABC { void bar(); }; } - /// inline int x = [](){ return 0; }; + /// template void foo() { void bar(); } + /// template void foo2() { class ABC { void bar(); }; } + /// template inline int x = [](){ return 0; }(); /// \endcode - bool isInLocalScope() const; + bool isInLocalScopeForInstantiation() const; /// If this decl is defined inside a function/method/block it returns /// the corresponding DeclContext, otherwise it returns null. @@ -1024,8 +1047,16 @@ public: /// If this is a declaration that describes some template, this /// method returns that template declaration. + /// + /// Note that this returns nullptr for partial specializations, because they + /// are not modeled as TemplateDecls. Use getDescribedTemplateParams to handle + /// those cases. TemplateDecl *getDescribedTemplate() const; + /// If this is a declaration that describes some template or partial + /// specialization, this returns the corresponding template parameter list. + const TemplateParameterList *getDescribedTemplateParams() const; + /// Returns the function itself, or the templated function if this is a /// function template. FunctionDecl *getAsFunction() LLVM_READONLY; diff --git a/gnu/llvm/clang/include/clang/AST/DeclCXX.h b/gnu/llvm/clang/include/clang/AST/DeclCXX.h index 2e8e31dbf4c..2b8d7e879a0 100644 --- a/gnu/llvm/clang/include/clang/AST/DeclCXX.h +++ b/gnu/llvm/clang/include/clang/AST/DeclCXX.h @@ -15,7 +15,6 @@ #ifndef LLVM_CLANG_AST_DECLCXX_H #define LLVM_CLANG_AST_DECLCXX_H -#include "clang/AST/ASTContext.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" @@ -40,6 +39,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" @@ -53,6 +53,7 @@ namespace clang { +class ASTContext; class ClassTemplateDecl; class ConstructorUsingShadowDecl; class CXXBasePath; @@ -711,6 +712,13 @@ public: !data().DefaultedMoveConstructorIsDeleted; } + /// \c true if we know for sure that this class has a single, + /// accessible, unambiguous copy assignment operator that is not deleted. + bool hasSimpleCopyAssignment() const { + return !hasUserDeclaredCopyAssignment() && + !data().DefaultedCopyAssignmentIsDeleted; + } + /// \c true if we know for sure that this class has a single, /// accessible, unambiguous move assignment operator that is not deleted. bool hasSimpleMoveAssignment() const { @@ -871,6 +879,15 @@ public: return data().UserDeclaredSpecialMembers & SMF_CopyAssignment; } + /// Set that we attempted to declare an implicit copy assignment + /// operator, but overload resolution failed so we deleted it. + void setImplicitCopyAssignmentIsDeleted() { + assert((data().DefaultedCopyAssignmentIsDeleted || + needsOverloadResolutionForCopyAssignment()) && + "copy assignment should not be deleted"); + data().DefaultedCopyAssignmentIsDeleted = true; + } + /// Determine whether this class needs an implicit copy /// assignment operator to be lazily declared. bool needsImplicitCopyAssignment() const { @@ -880,7 +897,16 @@ public: /// Determine whether we need to eagerly declare a defaulted copy /// assignment operator for this class. bool needsOverloadResolutionForCopyAssignment() const { - return data().HasMutableFields; + // C++20 [class.copy.assign]p2: + // If the class definition declares a move constructor or move assignment + // operator, the implicitly declared copy assignment operator is defined + // as deleted. + // In MSVC mode, sometimes a declared move constructor does not delete an + // implicit copy assignment, so defer this choice to Sema. + if (data().UserDeclaredSpecialMembers & + (SMF_MoveConstructor | SMF_MoveAssignment)) + return true; + return data().NeedOverloadResolutionForCopyAssignment; } /// Determine whether an implicit copy assignment operator for this @@ -998,6 +1024,9 @@ public: return static_cast(getLambdaData().CaptureDefault); } + /// Set the captures for this lambda closure type. + void setCaptures(ArrayRef Captures); + /// For a closure type, retrieve the mapping from captured /// variables and \c this to the non-static data members that store the /// values or references of the captures. @@ -1029,6 +1058,8 @@ public: : nullptr; } + unsigned capture_size() const { return getLambdaData().NumCaptures; } + using conversion_iterator = UnresolvedSetIterator; conversion_iterator conversion_begin() const { @@ -1166,7 +1197,7 @@ public: bool defaultedDefaultConstructorIsConstexpr() const { return data().DefaultedDefaultConstructorIsConstexpr && (!isUnion() || hasInClassInitializer() || !hasVariantMembers() || - getASTContext().getLangOpts().CPlusPlus2a); + getLangOpts().CPlusPlus20); } /// Determine whether this class has a constexpr default constructor. @@ -1258,7 +1289,7 @@ public: /// would be constexpr. bool defaultedDestructorIsConstexpr() const { return data().DefaultedDestructorIsConstexpr && - getASTContext().getLangOpts().CPlusPlus2a; + getLangOpts().CPlusPlus20; } /// Determine whether this class has a constexpr destructor. @@ -1355,10 +1386,10 @@ public: /// /// Only in C++17 and beyond, are lambdas literal types. bool isLiteral() const { - ASTContext &Ctx = getASTContext(); - return (Ctx.getLangOpts().CPlusPlus2a ? hasConstexprDestructor() + const LangOptions &LangOpts = getLangOpts(); + return (LangOpts.CPlusPlus20 ? hasConstexprDestructor() : hasTrivialDestructor()) && - (!isLambda() || Ctx.getLangOpts().CPlusPlus17) && + (!isLambda() || LangOpts.CPlusPlus17) && !hasNonLiteralTypeFieldsOrBases() && (isAggregate() || isLambda() || hasConstexprNonCopyMoveConstructor() || @@ -1517,14 +1548,8 @@ public: /// returns false if the class has non-computable base classes. /// /// \param BaseMatches Callback invoked for each (direct or indirect) base - /// class of this type, or if \p AllowShortCircuit is true then until a call - /// returns false. - /// - /// \param AllowShortCircuit if false, forces the callback to be called - /// for every base class, even if a dependent or non-matching base was - /// found. - bool forallBases(ForallBasesCallback BaseMatches, - bool AllowShortCircuit = true) const; + /// class of this type until a call returns false. + bool forallBases(ForallBasesCallback BaseMatches) const; /// Function type used by lookupInBases() to determine whether a /// specific base class subobject matches the lookup criteria. @@ -1696,6 +1721,10 @@ public: /// actually abstract. bool mayBeAbstract() const; + /// Determine whether it's impossible for a class to be derived from this + /// class. This is best-effort, and may conservatively return false. + bool isEffectivelyFinal() const; + /// If this is the closure type of a lambda expression, retrieve the /// number to be used for name mangling in the Itanium C++ ABI. /// @@ -2037,7 +2066,8 @@ public: method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; - using overridden_method_range= ASTContext::overridden_method_range; + using overridden_method_range = llvm::iterator_range< + llvm::TinyPtrVector::const_iterator>; overridden_method_range overridden_methods() const; @@ -2417,17 +2447,6 @@ class CXXConstructorDecl final : ExplicitSpecKind::ResolvedFalse); } - void setExplicitSpecifier(ExplicitSpecifier ES) { - assert((!ES.getExpr() || - CXXConstructorDeclBits.HasTrailingExplicitSpecifier) && - "cannot set this explicit specifier. no trail-allocated space for " - "explicit"); - if (ES.getExpr()) - *getCanonicalDecl()->getTrailingObjects() = ES; - else - CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit(); - } - enum TraillingAllocKind { TAKInheritsConstructor = 1, TAKHasTailExplicit = 1 << 1, @@ -2453,6 +2472,17 @@ public: InheritedConstructor Inherited = InheritedConstructor(), Expr *TrailingRequiresClause = nullptr); + void setExplicitSpecifier(ExplicitSpecifier ES) { + assert((!ES.getExpr() || + CXXConstructorDeclBits.HasTrailingExplicitSpecifier) && + "cannot set this explicit specifier. no trail-allocated space for " + "explicit"); + if (ES.getExpr()) + *getCanonicalDecl()->getTrailingObjects() = ES; + else + CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit(); + } + ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->getExplicitSpecifierInternal(); } @@ -2724,8 +2754,6 @@ class CXXConversionDecl : public CXXMethodDecl { ExplicitSpecifier ExplicitSpec; - void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } - public: friend class ASTDeclReader; friend class ASTDeclWriter; @@ -2747,6 +2775,7 @@ public: /// Return true if the declartion is already resolved to be explicit. bool isExplicit() const { return getExplicitSpecifier().isExplicit(); } + void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } /// Returns the type that this conversion function is converting to. QualType getConversionType() const { @@ -3964,6 +3993,81 @@ public: IdentifierInfo* getSetterId() const { return SetterId; } }; +/// Parts of a decomposed MSGuidDecl. Factored out to avoid unnecessary +/// dependencies on DeclCXX.h. +struct MSGuidDeclParts { + /// {01234567-... + uint32_t Part1; + /// ...-89ab-... + uint16_t Part2; + /// ...-cdef-... + uint16_t Part3; + /// ...-0123-456789abcdef} + uint8_t Part4And5[8]; + + uint64_t getPart4And5AsUint64() const { + uint64_t Val; + memcpy(&Val, &Part4And5, sizeof(Part4And5)); + return Val; + } +}; + +/// A global _GUID constant. These are implicitly created by UuidAttrs. +/// +/// struct _declspec(uuid("01234567-89ab-cdef-0123-456789abcdef")) X{}; +/// +/// X is a CXXRecordDecl that contains a UuidAttr that references the (unique) +/// MSGuidDecl for the specified UUID. +class MSGuidDecl : public ValueDecl, + public Mergeable, + public llvm::FoldingSetNode { +public: + using Parts = MSGuidDeclParts; + +private: + /// The decomposed form of the UUID. + Parts PartVal; + + /// The resolved value of the UUID as an APValue. Computed on demand and + /// cached. + mutable APValue APVal; + + void anchor() override; + + MSGuidDecl(DeclContext *DC, QualType T, Parts P); + + static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); + static MSGuidDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Only ASTContext::getMSGuidDecl and deserialization create these. + friend class ASTContext; + friend class ASTReader; + friend class ASTDeclReader; + +public: + /// Print this UUID in a human-readable format. + void printName(llvm::raw_ostream &OS) const override; + + /// Get the decomposed parts of this declaration. + Parts getParts() const { return PartVal; } + + /// Get the value of this MSGuidDecl as an APValue. This may fail and return + /// an absent APValue if the type of the declaration is not of the expected + /// shape. + APValue &getAsAPValue() const; + + static void Profile(llvm::FoldingSetNodeID &ID, Parts P) { + ID.AddInteger(P.Part1); + ID.AddInteger(P.Part2); + ID.AddInteger(P.Part3); + ID.AddInteger(P.getPart4And5AsUint64()); + } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, PartVal); } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Decl::MSGuid; } +}; + /// Insertion operator for diagnostics. This allows sending an AccessSpecifier /// into a diagnostic with <<. const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/gnu/llvm/clang/include/clang/AST/DeclGroup.h b/gnu/llvm/clang/include/clang/AST/DeclGroup.h index 2be9dae9431..672b7b0a9fe 100644 --- a/gnu/llvm/clang/include/clang/AST/DeclGroup.h +++ b/gnu/llvm/clang/include/clang/AST/DeclGroup.h @@ -147,7 +147,7 @@ namespace llvm { return clang::DeclGroupRef::getFromOpaquePtr(P); } - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm diff --git a/gnu/llvm/clang/include/clang/AST/DeclObjC.h b/gnu/llvm/clang/include/clang/AST/DeclObjC.h index b98aef6b499..5613ed8370c 100644 --- a/gnu/llvm/clang/include/clang/AST/DeclObjC.h +++ b/gnu/llvm/clang/include/clang/AST/DeclObjC.h @@ -15,6 +15,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclObjCCommon.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/SelectorLocationsKind.h" @@ -402,7 +403,7 @@ public: } /// createImplicitParams - Used to lazily create the self and cmd - /// implict parameters. This must be called prior to using getSelfDecl() + /// implicit parameters. This must be called prior to using getSelfDecl() /// or getCmdDecl(). The call is ignored if the implicit parameters /// have already been created. void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); @@ -742,34 +743,6 @@ class ObjCPropertyDecl : public NamedDecl { void anchor() override; public: - enum PropertyAttributeKind { - OBJC_PR_noattr = 0x00, - OBJC_PR_readonly = 0x01, - OBJC_PR_getter = 0x02, - OBJC_PR_assign = 0x04, - OBJC_PR_readwrite = 0x08, - OBJC_PR_retain = 0x10, - OBJC_PR_copy = 0x20, - OBJC_PR_nonatomic = 0x40, - OBJC_PR_setter = 0x80, - OBJC_PR_atomic = 0x100, - OBJC_PR_weak = 0x200, - OBJC_PR_strong = 0x400, - OBJC_PR_unsafe_unretained = 0x800, - /// Indicates that the nullability of the type was spelled with a - /// property attribute rather than a type qualifier. - OBJC_PR_nullability = 0x1000, - OBJC_PR_null_resettable = 0x2000, - OBJC_PR_class = 0x4000, - OBJC_PR_direct = 0x8000 - // Adding a property should change NumPropertyAttrsBits - }; - - enum { - /// Number of bits fitting all the property attributes. - NumPropertyAttrsBits = 16 - }; - enum SetterKind { Assign, Retain, Copy, Weak }; enum PropertyControl { None, Required, Optional }; @@ -782,8 +755,8 @@ private: QualType DeclType; TypeSourceInfo *DeclTypeSourceInfo; - unsigned PropertyAttributes : NumPropertyAttrsBits; - unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; + unsigned PropertyAttributes : NumObjCPropertyAttrsBits; + unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits; // \@required/\@optional unsigned PropertyImplementation : 2; @@ -810,15 +783,14 @@ private: ObjCIvarDecl *PropertyIvarDecl = nullptr; ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - SourceLocation AtLocation, SourceLocation LParenLocation, - QualType T, TypeSourceInfo *TSI, - PropertyControl propControl) - : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), - LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), - PropertyAttributes(OBJC_PR_noattr), - PropertyAttributesAsWritten(OBJC_PR_noattr), - PropertyImplementation(propControl), GetterName(Selector()), - SetterName(Selector()) {} + SourceLocation AtLocation, SourceLocation LParenLocation, + QualType T, TypeSourceInfo *TSI, PropertyControl propControl) + : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), + LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), + PropertyAttributes(ObjCPropertyAttribute::kind_noattr), + PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr), + PropertyImplementation(propControl), GetterName(Selector()), + SetterName(Selector()) {} public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, @@ -850,11 +822,11 @@ public: /// type. QualType getUsageType(QualType objectType) const; - PropertyAttributeKind getPropertyAttributes() const { - return PropertyAttributeKind(PropertyAttributes); + ObjCPropertyAttribute::Kind getPropertyAttributes() const { + return ObjCPropertyAttribute::Kind(PropertyAttributes); } - void setPropertyAttributes(PropertyAttributeKind PRVal) { + void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) { PropertyAttributes |= PRVal; } @@ -862,11 +834,11 @@ public: PropertyAttributes = PRVal; } - PropertyAttributeKind getPropertyAttributesAsWritten() const { - return PropertyAttributeKind(PropertyAttributesAsWritten); + ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const { + return ObjCPropertyAttribute::Kind(PropertyAttributesAsWritten); } - void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { + void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal) { PropertyAttributesAsWritten = PRVal; } @@ -874,23 +846,28 @@ public: /// isReadOnly - Return true iff the property has a setter. bool isReadOnly() const { - return (PropertyAttributes & OBJC_PR_readonly); + return (PropertyAttributes & ObjCPropertyAttribute::kind_readonly); } /// isAtomic - Return true if the property is atomic. bool isAtomic() const { - return (PropertyAttributes & OBJC_PR_atomic); + return (PropertyAttributes & ObjCPropertyAttribute::kind_atomic); } /// isRetaining - Return true if the property retains its value. bool isRetaining() const { - return (PropertyAttributes & - (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); + return (PropertyAttributes & (ObjCPropertyAttribute::kind_retain | + ObjCPropertyAttribute::kind_strong | + ObjCPropertyAttribute::kind_copy)); } bool isInstanceProperty() const { return !isClassProperty(); } - bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; } - bool isDirectProperty() const { return PropertyAttributes & OBJC_PR_direct; } + bool isClassProperty() const { + return PropertyAttributes & ObjCPropertyAttribute::kind_class; + } + bool isDirectProperty() const { + return PropertyAttributes & ObjCPropertyAttribute::kind_direct; + } ObjCPropertyQueryKind getQueryKind() const { return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class : @@ -906,13 +883,13 @@ public: /// the property setter. This is only valid if the property has been /// defined to have a setter. SetterKind getSetterKind() const { - if (PropertyAttributes & OBJC_PR_strong) + if (PropertyAttributes & ObjCPropertyAttribute::kind_strong) return getType()->isBlockPointerType() ? Copy : Retain; - if (PropertyAttributes & OBJC_PR_retain) + if (PropertyAttributes & ObjCPropertyAttribute::kind_retain) return Retain; - if (PropertyAttributes & OBJC_PR_copy) + if (PropertyAttributes & ObjCPropertyAttribute::kind_copy) return Copy; - if (PropertyAttributes & OBJC_PR_weak) + if (PropertyAttributes & ObjCPropertyAttribute::kind_weak) return Weak; return Assign; } @@ -2692,9 +2669,7 @@ public: /// Get the name of the class associated with this interface. // // FIXME: Move to StringRef API. - std::string getNameAsString() const { - return getName(); - } + std::string getNameAsString() const { return std::string(getName()); } /// Produce a name to be used for class's metadata. It comes either via /// class's objc_runtime_name attribute or class name. @@ -2908,11 +2883,11 @@ ObjCInterfaceDecl::filtered_category_iterator::operator++() { } inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) { - return !Cat->isHidden(); + return Cat->isUnconditionallyVisible(); } inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { - return Cat->IsClassExtension() && !Cat->isHidden(); + return Cat->IsClassExtension() && Cat->isUnconditionallyVisible(); } inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { diff --git a/gnu/llvm/clang/include/clang/AST/DeclObjCCommon.h b/gnu/llvm/clang/include/clang/AST/DeclObjCCommon.h new file mode 100644 index 00000000000..5f03bce6e9a --- /dev/null +++ b/gnu/llvm/clang/include/clang/AST/DeclObjCCommon.h @@ -0,0 +1,55 @@ +//===- DeclObjCCommon.h - Classes for representing declarations -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains common ObjC enums and classes used in AST and +// Sema. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H +#define LLVM_CLANG_AST_DECLOBJC_COMMON_H + +namespace clang { + +/// ObjCPropertyAttribute::Kind - list of property attributes. +/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes.s +namespace ObjCPropertyAttribute { +enum Kind { + kind_noattr = 0x00, + kind_readonly = 0x01, + kind_getter = 0x02, + kind_assign = 0x04, + kind_readwrite = 0x08, + kind_retain = 0x10, + kind_copy = 0x20, + kind_nonatomic = 0x40, + kind_setter = 0x80, + kind_atomic = 0x100, + kind_weak = 0x200, + kind_strong = 0x400, + kind_unsafe_unretained = 0x800, + /// Indicates that the nullability of the type was spelled with a + /// property attribute rather than a type qualifier. + kind_nullability = 0x1000, + kind_null_resettable = 0x2000, + kind_class = 0x4000, + kind_direct = 0x8000, + // Adding a property should change NumObjCPropertyAttrsBits + // Also, don't forget to update the Clang C API at CXObjCPropertyAttrKind and + // clang_Cursor_getObjCPropertyAttributes. +}; +} // namespace ObjCPropertyAttribute::Kind + +enum { + /// Number of bits fitting all the property attributes. + NumObjCPropertyAttrsBits = 16 +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H diff --git a/gnu/llvm/clang/include/clang/AST/DeclOpenMP.h b/gnu/llvm/clang/include/clang/AST/DeclOpenMP.h index 437feaba28f..154ecb97769 100644 --- a/gnu/llvm/clang/include/clang/AST/DeclOpenMP.h +++ b/gnu/llvm/clang/include/clang/AST/DeclOpenMP.h @@ -129,7 +129,7 @@ private: /// the declare reduction construct is declared inside compound statement. LazyDeclPtr PrevDeclInScope; - virtual void anchor(); + void anchor() override; OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType Ty, @@ -228,7 +228,7 @@ class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext { LazyDeclPtr PrevDeclInScope; - virtual void anchor(); + void anchor() override; OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType Ty, diff --git a/gnu/llvm/clang/include/clang/AST/DeclTemplate.h b/gnu/llvm/clang/include/clang/AST/DeclTemplate.h index 7a9f623d815..e9c4879b41e 100755 --- a/gnu/llvm/clang/include/clang/AST/DeclTemplate.h +++ b/gnu/llvm/clang/include/clang/AST/DeclTemplate.h @@ -1891,6 +1891,10 @@ public: return *TemplateArgs; } + void setTemplateArgs(TemplateArgumentList *Args) { + TemplateArgs = Args; + } + /// Determine the kind of specialization that this /// declaration represents. TemplateSpecializationKind getSpecializationKind() const { @@ -1923,6 +1927,10 @@ public: getTemplateSpecializationKind()); } + void setSpecializedTemplate(ClassTemplateDecl *Specialized) { + SpecializedTemplate = Specialized; + } + void setSpecializationKind(TemplateSpecializationKind TSK) { SpecializationKind = TSK; } diff --git a/gnu/llvm/clang/include/clang/AST/DependenceFlags.h b/gnu/llvm/clang/include/clang/AST/DependenceFlags.h new file mode 100644 index 00000000000..14a7ffaecb2 --- /dev/null +++ b/gnu/llvm/clang/include/clang/AST/DependenceFlags.h @@ -0,0 +1,284 @@ +//===--- DependenceFlags.h ------------------------------------------------===// +// +// 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_AST_DEPENDENCEFLAGS_H +#define LLVM_CLANG_AST_DEPENDENCEFLAGS_H + +#include "clang/Basic/BitmaskEnum.h" +#include "llvm/ADT/BitmaskEnum.h" +#include + +namespace clang { +struct ExprDependenceScope { + enum ExprDependence : uint8_t { + UnexpandedPack = 1, + // This expr depends in any way on + // - a template parameter, it implies that the resolution of this expr may + // cause instantiation to fail + // - or an error (often in a non-template context) + // + // Note that C++ standard doesn't define the instantiation-dependent term, + // we follow the formal definition coming from the Itanium C++ ABI, and + // extend it to errors. + Instantiation = 2, + // The type of this expr depends on a template parameter, or an error. + Type = 4, + // The value of this expr depends on a template parameter, or an error. + Value = 8, + + // clang extension: this expr contains or references an error, and is + // considered dependent on how that error is resolved. + Error = 16, + + None = 0, + All = 31, + + TypeValue = Type | Value, + TypeInstantiation = Type | Instantiation, + ValueInstantiation = Value | Instantiation, + TypeValueInstantiation = Type | Value | Instantiation, + + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) + }; +}; +using ExprDependence = ExprDependenceScope::ExprDependence; + +struct TypeDependenceScope { + enum TypeDependence : uint8_t { + /// Whether this type contains an unexpanded parameter pack + /// (for C++11 variadic templates) + UnexpandedPack = 1, + /// Whether this type somehow involves + /// - a template parameter, even if the resolution of the type does not + /// depend on a template parameter. + /// - or an error. + Instantiation = 2, + /// Whether this type + /// - is a dependent type (C++ [temp.dep.type]) + /// - or it somehow involves an error, e.g. decltype(recovery-expr) + Dependent = 4, + /// Whether this type is a variably-modified type (C99 6.7.5). + VariablyModified = 8, + + /// Whether this type references an error, e.g. decltype(err-expression) + /// yields an error type. + Error = 16, + + None = 0, + All = 31, + + DependentInstantiation = Dependent | Instantiation, + + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) + }; +}; +using TypeDependence = TypeDependenceScope::TypeDependence; + +#define LLVM_COMMON_DEPENDENCE(NAME) \ + struct NAME##Scope { \ + enum NAME : uint8_t { \ + UnexpandedPack = 1, \ + Instantiation = 2, \ + Dependent = 4, \ + Error = 8, \ + \ + None = 0, \ + DependentInstantiation = Dependent | Instantiation, \ + All = 15, \ + \ + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \ + }; \ + }; \ + using NAME = NAME##Scope::NAME; + +LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) +LLVM_COMMON_DEPENDENCE(TemplateNameDependence) +LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) +#undef LLVM_COMMON_DEPENDENCE + +// A combined space of all dependence concepts for all node types. +// Used when aggregating dependence of nodes of different types. +class Dependence { +public: + enum Bits : uint8_t { + None = 0, + + // Contains a template parameter pack that wasn't expanded. + UnexpandedPack = 1, + // Depends on a template parameter or an error in some way. + // Validity depends on how the template is instantiated or the error is + // resolved. + Instantiation = 2, + // Expression type depends on template context, or an error. + // Value and Instantiation should also be set. + Type = 4, + // Expression value depends on template context, or an error. + // Instantiation should also be set. + Value = 8, + // Depends on template context, or an error. + // The type/value distinction is only meaningful for expressions. + Dependent = Type | Value, + // Includes an error, and depends on how it is resolved. + Error = 16, + // Type depends on a runtime value (variable-length array). + VariablyModified = 32, + + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) + }; + + Dependence() : V(None) {} + + Dependence(TypeDependence D) + : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) | + translate(D, TypeDependence::Instantiation, Instantiation) | + translate(D, TypeDependence::Dependent, Dependent) | + translate(D, TypeDependence::Error, Error) | + translate(D, TypeDependence::VariablyModified, VariablyModified)) {} + + Dependence(ExprDependence D) + : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) | + translate(D, ExprDependence::Instantiation, Instantiation) | + translate(D, ExprDependence::Type, Type) | + translate(D, ExprDependence::Value, Value) | + translate(D, ExprDependence::Error, Error)) {} + + Dependence(NestedNameSpecifierDependence D) : + V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) | + translate(D, NNSDependence::Instantiation, Instantiation) | + translate(D, NNSDependence::Dependent, Dependent) | + translate(D, NNSDependence::Error, Error)) {} + + Dependence(TemplateArgumentDependence D) + : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) | + translate(D, TADependence::Instantiation, Instantiation) | + translate(D, TADependence::Dependent, Dependent) | + translate(D, TADependence::Error, Error)) {} + + Dependence(TemplateNameDependence D) + : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) | + translate(D, TNDependence::Instantiation, Instantiation) | + translate(D, TNDependence::Dependent, Dependent) | + translate(D, TNDependence::Error, Error)) {} + + TypeDependence type() const { + return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | + translate(V, Instantiation, TypeDependence::Instantiation) | + translate(V, Dependent, TypeDependence::Dependent) | + translate(V, Error, TypeDependence::Error) | + translate(V, VariablyModified, TypeDependence::VariablyModified); + } + + ExprDependence expr() const { + return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) | + translate(V, Instantiation, ExprDependence::Instantiation) | + translate(V, Type, ExprDependence::Type) | + translate(V, Value, ExprDependence::Value) | + translate(V, Error, ExprDependence::Error); + } + + NestedNameSpecifierDependence nestedNameSpecifier() const { + return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) | + translate(V, Instantiation, NNSDependence::Instantiation) | + translate(V, Dependent, NNSDependence::Dependent) | + translate(V, Error, NNSDependence::Error); + } + + TemplateArgumentDependence templateArgument() const { + return translate(V, UnexpandedPack, TADependence::UnexpandedPack) | + translate(V, Instantiation, TADependence::Instantiation) | + translate(V, Dependent, TADependence::Dependent) | + translate(V, Error, TADependence::Error); + } + + TemplateNameDependence templateName() const { + return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) | + translate(V, Instantiation, TNDependence::Instantiation) | + translate(V, Dependent, TNDependence::Dependent) | + translate(V, Error, TNDependence::Error); + } + +private: + Bits V; + + template + static U translate(T Bits, T FromBit, U ToBit) { + return (Bits & FromBit) ? ToBit : static_cast(0); + } + + // Abbreviations to make conversions more readable. + using NNSDependence = NestedNameSpecifierDependence; + using TADependence = TemplateArgumentDependence; + using TNDependence = TemplateNameDependence; +}; + +/// Computes dependencies of a reference with the name having template arguments +/// with \p TA dependencies. +inline ExprDependence toExprDependence(TemplateArgumentDependence TA) { + return Dependence(TA).expr(); +} +inline ExprDependence toExprDependence(TypeDependence D) { + return Dependence(D).expr(); +} +// Note: it's often necessary to strip `Dependent` from qualifiers. +// If V:: refers to the current instantiation, NNS is considered dependent +// but the containing V::foo likely isn't. +inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) { + return Dependence(D).expr(); +} +inline ExprDependence turnTypeToValueDependence(ExprDependence D) { + // Type-dependent expressions are always be value-dependent, so we simply drop + // type dependency. + return D & ~ExprDependence::Type; +} +inline ExprDependence turnValueToTypeDependence(ExprDependence D) { + // Type-dependent expressions are always be value-dependent. + if (D & ExprDependence::Value) + D |= ExprDependence::Type; + return D; +} + +// Returned type-dependence will never have VariablyModified set. +inline TypeDependence toTypeDependence(ExprDependence D) { + return Dependence(D).type(); +} +inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) { + return Dependence(D).type(); +} +inline TypeDependence toTypeDependence(TemplateNameDependence D) { + return Dependence(D).type(); +} +inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { + return Dependence(D).type(); +} + +inline NestedNameSpecifierDependence +toNestedNameSpecifierDependendence(TypeDependence D) { + return Dependence(D).nestedNameSpecifier(); +} + +inline TemplateArgumentDependence +toTemplateArgumentDependence(TypeDependence D) { + return Dependence(D).templateArgument(); +} +inline TemplateArgumentDependence +toTemplateArgumentDependence(TemplateNameDependence D) { + return Dependence(D).templateArgument(); +} +inline TemplateArgumentDependence +toTemplateArgumentDependence(ExprDependence D) { + return Dependence(D).templateArgument(); +} + +inline TemplateNameDependence +toTemplateNameDependence(NestedNameSpecifierDependence D) { + return Dependence(D).templateName(); +} + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +} // namespace clang +#endif diff --git a/gnu/llvm/clang/include/clang/AST/Expr.h b/gnu/llvm/clang/include/clang/AST/Expr.h index 7ff53ef7c65..c13b9711928 100644 --- a/gnu/llvm/clang/include/clang/AST/Expr.h +++ b/gnu/llvm/clang/include/clang/AST/Expr.h @@ -15,8 +15,10 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTVector.h" +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" @@ -28,10 +30,10 @@ #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" -#include "llvm/ADT/iterator.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" @@ -116,23 +118,26 @@ public: Expr &operator=(Expr&&) = delete; protected: - Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) - : ValueStmt(SC) - { - ExprBits.TypeDependent = TD; - ExprBits.ValueDependent = VD; - ExprBits.InstantiationDependent = ID; + Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK) + : ValueStmt(SC) { + ExprBits.Dependent = 0; ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; assert(ExprBits.ObjectKind == OK && "truncated kind"); - ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; setType(T); } /// Construct an empty expression. explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { } + /// Each concrete expr subclass is expected to compute its dependence and call + /// this in the constructor. + void setDependence(ExprDependence Deps) { + ExprBits.Dependent = static_cast(Deps); + } + friend class ASTImporter; // Sets dependence dircetly. + friend class ASTStmtReader; // Sets dependence dircetly. + public: QualType getType() const { return TR; } void setType(QualType t) { @@ -148,24 +153,29 @@ public: TR = t; } - /// isValueDependent - Determines whether this expression is - /// value-dependent (C++ [temp.dep.constexpr]). For example, the - /// array bound of "Chars" in the following example is + ExprDependence getDependence() const { + return static_cast(ExprBits.Dependent); + } + + /// Determines whether the value of this expression depends on + /// - a template parameter (C++ [temp.dep.constexpr]) + /// - or an error, whose resolution is unknown + /// + /// For example, the array bound of "Chars" in the following example is /// value-dependent. /// @code /// template struct meta_string; /// @endcode - bool isValueDependent() const { return ExprBits.ValueDependent; } - - /// Set whether this expression is value-dependent or not. - void setValueDependent(bool VD) { - ExprBits.ValueDependent = VD; + bool isValueDependent() const { + return static_cast(getDependence() & ExprDependence::Value); } - /// isTypeDependent - Determines whether this expression is - /// type-dependent (C++ [temp.dep.expr]), which means that its type - /// could change from one template instantiation to the next. For - /// example, the expressions "x" and "x + y" are type-dependent in + /// Determines whether the type of this expression depends on + /// - a template paramter (C++ [temp.dep.expr], which means that its type + /// could change from one template instantiation to the next) + /// - or an error + /// + /// For example, the expressions "x" and "x + y" are type-dependent in /// the following code, but "y" is not type-dependent: /// @code /// template @@ -173,16 +183,15 @@ public: /// x + y; /// } /// @endcode - bool isTypeDependent() const { return ExprBits.TypeDependent; } - - /// Set whether this expression is type-dependent or not. - void setTypeDependent(bool TD) { - ExprBits.TypeDependent = TD; + bool isTypeDependent() const { + return static_cast(getDependence() & ExprDependence::Type); } /// Whether this expression is instantiation-dependent, meaning that - /// it depends in some way on a template parameter, even if neither its type - /// nor (constant) value can change due to the template instantiation. + /// it depends in some way on + /// - a template parameter (even if neither its type nor (constant) value + /// can change due to the template instantiation) + /// - or an error /// /// In the following example, the expression \c sizeof(sizeof(T() + T())) is /// instantiation-dependent (since it involves a template parameter \c T), but @@ -197,13 +206,14 @@ public: /// } /// \endcode /// + /// \code + /// void func(int) { + /// func(); // the expression is instantiation-dependent, because it depends + /// // on an error. + /// } + /// \endcode bool isInstantiationDependent() const { - return ExprBits.InstantiationDependent; - } - - /// Set whether this expression is instantiation-dependent or not. - void setInstantiationDependent(bool ID) { - ExprBits.InstantiationDependent = ID; + return static_cast(getDependence() & ExprDependence::Instantiation); } /// Whether this expression contains an unexpanded parameter @@ -221,19 +231,24 @@ public: /// The expressions \c args and \c static_cast(args) both /// contain parameter packs. bool containsUnexpandedParameterPack() const { - return ExprBits.ContainsUnexpandedParameterPack; + return static_cast(getDependence() & ExprDependence::UnexpandedPack); } - /// Set the bit that describes whether this expression - /// contains an unexpanded parameter pack. - void setContainsUnexpandedParameterPack(bool PP = true) { - ExprBits.ContainsUnexpandedParameterPack = PP; + /// Whether this expression contains subexpressions which had errors, e.g. a + /// TypoExpr. + bool containsErrors() const { + return static_cast(getDependence() & ExprDependence::Error); } /// getExprLoc - Return the preferred location for the arrow when diagnosing /// a problem with a generic expression. SourceLocation getExprLoc() const LLVM_READONLY; + /// Determine whether an lvalue-to-rvalue conversion should implicitly be + /// applied to this expression if it appears as a discarded-value expression + /// in C++11 onwards. This applies to certain forms of volatile glvalues. + bool isReadIfDiscardedInCPlusPlus11() const; + /// isUnusedResultAWarning - Return true if this immediate expression should /// be warned about if the result is unused. If so, fill in expr, location, /// and ranges with expr to warn on and source locations/ranges appropriate @@ -473,6 +488,11 @@ public: /// Returns whether this expression refers to a vector element. bool refersToVectorElement() const; + /// Returns whether this expression refers to a matrix element. + bool refersToMatrixElement() const { + return getObjectKind() == OK_MatrixComponent; + } + /// Returns whether this expression refers to a global register /// variable. bool refersToGlobalRegisterVar() const; @@ -693,7 +713,8 @@ public: /// Evaluate an expression that is required to be a constant expression. bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, - const ASTContext &Ctx) const; + const ASTContext &Ctx, + bool InPlace = false) const; /// If the current Expr is a pointer, this will try to statically /// determine the number of bytes available where the pointer is pointing. @@ -952,11 +973,11 @@ protected: Stmt *SubExpr; FullExpr(StmtClass SC, Expr *subexpr) - : Expr(SC, subexpr->getType(), - subexpr->getValueKind(), subexpr->getObjectKind(), - subexpr->isTypeDependent(), subexpr->isValueDependent(), - subexpr->isInstantiationDependent(), - subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {} + : Expr(SC, subexpr->getType(), subexpr->getValueKind(), + subexpr->getObjectKind()), + SubExpr(subexpr) { + setDependence(computeDependence(this)); + } FullExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {} public: @@ -979,11 +1000,14 @@ class ConstantExpr final : public FullExpr, private llvm::TrailingObjects { static_assert(std::is_same::value, - "this class assumes llvm::APInt::WordType is uint64_t for " - "trail-allocated storage"); + "ConstantExpr assumes that llvm::APInt::WordType is uint64_t " + "for tail-allocated storage"); + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; public: - /// Describes the kind of result that can be trail-allocated. + /// Describes the kind of result that can be tail-allocated. enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue }; private: @@ -994,7 +1018,6 @@ private: return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64; } - void DefaultInit(ResultStorageKind StorageKind); uint64_t &Int64Result() { assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 && "invalid accessor"); @@ -1008,24 +1031,22 @@ private: "invalid accessor"); return *getTrailingObjects(); } - const APValue &APValueResult() const { + APValue &APValueResult() const { return const_cast(this)->APValueResult(); } - ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind); - ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty); + ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind, + bool IsImmediateInvocation); + ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind); public: - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; static ConstantExpr *Create(const ASTContext &Context, Expr *E, const APValue &Result); static ConstantExpr *Create(const ASTContext &Context, Expr *E, - ResultStorageKind Storage = RSK_None); + ResultStorageKind Storage = RSK_None, + bool IsImmediateInvocation = false); static ConstantExpr *CreateEmpty(const ASTContext &Context, - ResultStorageKind StorageKind, - EmptyShell Empty); + ResultStorageKind StorageKind); static ResultStorageKind getStorageKind(const APValue &Value); static ResultStorageKind getStorageKind(const Type *T, @@ -1053,8 +1074,14 @@ public: ResultStorageKind getResultStorageKind() const { return static_cast(ConstantExprBits.ResultKind); } + bool isImmediateInvocation() const { + return ConstantExprBits.IsImmediateInvocation; + } + bool hasAPValueResult() const { + return ConstantExprBits.APValueKind != APValue::None; + } APValue getAPValueResult() const; - const APValue &getResultAsAPValue() const { return APValueResult(); } + APValue &getResultAsAPValue() const { return APValueResult(); } llvm::APSInt getResultAsAPSInt() const; // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } @@ -1078,19 +1105,11 @@ class OpaqueValueExpr : public Expr { public: OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK, - ExprObjectKind OK = OK_Ordinary, - Expr *SourceExpr = nullptr) - : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType() || - (SourceExpr && SourceExpr->isTypeDependent()), - T->isDependentType() || - (SourceExpr && SourceExpr->isValueDependent()), - T->isInstantiationDependentType() || - (SourceExpr && SourceExpr->isInstantiationDependent()), - false), - SourceExpr(SourceExpr) { + ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr) + : Expr(OpaqueValueExprClass, T, VK, OK), SourceExpr(SourceExpr) { setIsUnique(false); OpaqueValueExprBits.Loc = Loc; + setDependence(computeDependence(this)); } /// Given an expression which invokes a copy constructor --- i.e. a @@ -1210,10 +1229,6 @@ class DeclRefExpr final /// Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} - /// Computes the type- and value-dependence flags for this - /// declaration reference expression. - void computeDependence(const ASTContext &Ctx); - public: DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, @@ -1490,7 +1505,7 @@ class FixedPointLiteral : public Expr, public APIntStorage { SourceLocation Loc; unsigned Scale; - /// \brief Construct an empty integer literal. + /// \brief Construct an empty fixed-point literal. explicit FixedPointLiteral(EmptyShell Empty) : Expr(FixedPointLiteralClass, Empty) {} @@ -1504,6 +1519,9 @@ class FixedPointLiteral : public Expr, public APIntStorage { QualType type, SourceLocation l, unsigned Scale); + /// Returns an empty fixed-point literal. + static FixedPointLiteral *Create(const ASTContext &C, EmptyShell Empty); + SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } @@ -1512,6 +1530,9 @@ class FixedPointLiteral : public Expr, public APIntStorage { void setLocation(SourceLocation Location) { Loc = Location; } + unsigned getScale() const { return Scale; } + void setScale(unsigned S) { Scale = S; } + static bool classof(const Stmt *T) { return T->getStmtClass() == FixedPointLiteralClass; } @@ -1544,10 +1565,10 @@ public: // type should be IntTy CharacterLiteral(unsigned value, CharacterKind kind, QualType type, SourceLocation l) - : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, - false, false), - Value(value), Loc(l) { + : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary), Value(value), + Loc(l) { CharacterLiteralBits.Kind = kind; + setDependence(ExprDependence::None); } /// Construct an empty character literal. @@ -1663,9 +1684,9 @@ class ImaginaryLiteral : public Expr { Stmt *Val; public: ImaginaryLiteral(Expr *val, QualType Ty) - : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), - Val(val) {} + : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary), Val(val) { + setDependence(ExprDependence::None); + } /// Build an empty imaginary literal. explicit ImaginaryLiteral(EmptyShell Empty) @@ -1902,13 +1923,17 @@ public: /// [C99 6.4.2.2] - A predefined identifier such as __func__. class PredefinedExpr final : public Expr, - private llvm::TrailingObjects { + private llvm::TrailingObjects { 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 { @@ -1921,12 +1946,18 @@ public: PrettyFunction, /// The same as PrettyFunction, except that the /// 'virtual' keyword is omitted for virtual member functions. - PrettyFunctionNoVirtual + PrettyFunctionNoVirtual, + UniqueStableNameType, + UniqueStableNameExpr, }; 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); @@ -1939,10 +1970,39 @@ private: *getTrailingObjects() = SL; } + void setTypeSourceInfo(TypeSourceInfo *Info) { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType && + "TypeSourceInfo only valid for UniqueStableName of a Type"); + *getTrailingObjects() = Info; + } + + void setExpr(Expr *E) { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr && + "TypeSourceInfo only valid for UniqueStableName of n Expression."); + *getTrailingObjects() = E; + } + + size_t numTrailingObjects(OverloadToken) const { + return hasFunctionName(); + } + + size_t numTrailingObjects(OverloadToken) const { + return getIdentKind() == UniqueStableNameType && !hasFunctionName(); + } + size_t numTrailingObjects(OverloadToken) 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, @@ -1967,8 +2027,34 @@ public: : nullptr; } + TypeSourceInfo *getTypeSourceInfo() { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType && + "TypeSourceInfo only valid for UniqueStableName of a Type"); + return *getTrailingObjects(); + } + + const TypeSourceInfo *getTypeSourceInfo() const { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType && + "TypeSourceInfo only valid for UniqueStableName of a Type"); + return *getTrailingObjects(); + } + + Expr *getExpr() { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr && + "TypeSourceInfo only valid for UniqueStableName of n Expression."); + return *getTrailingObjects(); + } + + const Expr *getExpr() const { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr && + "TypeSourceInfo only valid for UniqueStableName of n Expression."); + return *getTrailingObjects(); + } + static StringRef getIdentKindName(IdentKind IK); 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(); } @@ -1996,12 +2082,11 @@ class ParenExpr : public Expr { Stmt *Val; public: ParenExpr(SourceLocation l, SourceLocation r, Expr *val) - : Expr(ParenExprClass, val->getType(), - val->getValueKind(), val->getObjectKind(), - val->isTypeDependent(), val->isValueDependent(), - val->isInstantiationDependent(), - val->containsUnexpandedParameterPack()), - L(l), R(r), Val(val) {} + : Expr(ParenExprClass, val->getType(), val->getValueKind(), + val->getObjectKind()), + L(l), R(r), Val(val) { + setDependence(computeDependence(this)); + } /// Construct an empty parenthesized expression. explicit ParenExpr(EmptyShell Empty) @@ -2043,31 +2128,48 @@ public: /// applied to a non-complex value, the former returns its operand and the /// later returns zero in the type of the operand. /// -class UnaryOperator : public Expr { +class UnaryOperator final + : public Expr, + private llvm::TrailingObjects { Stmt *Val; + size_t numTrailingObjects(OverloadToken) const { + return UnaryOperatorBits.HasFPFeatures ? 1 : 0; + } + + FPOptionsOverride &getTrailingFPFeatures() { + assert(UnaryOperatorBits.HasFPFeatures); + return *getTrailingObjects(); + } + + const FPOptionsOverride &getTrailingFPFeatures() const { + assert(UnaryOperatorBits.HasFPFeatures); + return *getTrailingObjects(); + } + public: typedef UnaryOperatorKind Opcode; - UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK, - ExprObjectKind OK, SourceLocation l, bool CanOverflow) - : Expr(UnaryOperatorClass, type, VK, OK, - input->isTypeDependent() || type->isDependentType(), - input->isValueDependent(), - (input->isInstantiationDependent() || - type->isInstantiationDependentType()), - input->containsUnexpandedParameterPack()), - Val(input) { - UnaryOperatorBits.Opc = opc; - UnaryOperatorBits.CanOverflow = CanOverflow; - UnaryOperatorBits.Loc = l; - } +protected: + UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type, + ExprValueKind VK, ExprObjectKind OK, SourceLocation l, + bool CanOverflow, FPOptionsOverride FPFeatures); /// Build an empty unary operator. - explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) { + explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty) + : Expr(UnaryOperatorClass, Empty) { UnaryOperatorBits.Opc = UO_AddrOf; + UnaryOperatorBits.HasFPFeatures = HasFPFeatures; } +public: + static UnaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures); + + static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc, + QualType type, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, + bool CanOverflow, FPOptionsOverride FPFeatures); + Opcode getOpcode() const { return static_cast(UnaryOperatorBits.Opc); } @@ -2089,6 +2191,18 @@ public: bool canOverflow() const { return UnaryOperatorBits.CanOverflow; } void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; } + // Get the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + bool isFPContractableWithinStatement(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); + } + + // Get the FENV_ACCESS status of this operator. Only meaningful for + // operations on floating point types. + bool isFEnvAccessOn(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).getAllowFEnvAccess(); + } + /// isPostfix - Return true if this is a postfix operation, like x++. static bool isPostfix(Opcode Op) { return Op == UO_PostInc || Op == UO_PostDec; @@ -2155,6 +2269,37 @@ public: const_child_range children() const { return const_child_range(&Val, &Val + 1); } + + /// Is FPFeatures in Trailing Storage? + bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; } + +protected: + /// Get FPFeatures from trailing storage + FPOptionsOverride getStoredFPFeatures() const { + return getTrailingFPFeatures(); + } + + /// Set FPFeatures in trailing storage, used only by Serialization + void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; } + +public: + // Get the FP features status of this operator. Only meaningful for + // operations on floating point types. + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { + if (UnaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures().applyOverrides(LO); + return FPOptions::defaultWithoutTrailingStorage(LO); + } + FPOptionsOverride getFPOptionsOverride() const { + if (UnaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures(); + return FPOptionsOverride(); + } + + friend TrailingObjects; + friend class ASTReader; + friend class ASTStmtReader; + friend class ASTStmtWriter; }; /// Helper class for OffsetOfExpr. @@ -2379,17 +2524,17 @@ class UnaryExprOrTypeTraitExpr : public Expr { public: UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo, QualType resultType, SourceLocation op, - SourceLocation rp) : - Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary, - false, // Never type-dependent (C++ [temp.dep.expr]p3). - // Value-dependent if the argument is type-dependent. - TInfo->getType()->isDependentType(), - TInfo->getType()->isInstantiationDependentType(), - TInfo->getType()->containsUnexpandedParameterPack()), - OpLoc(op), RParenLoc(rp) { + SourceLocation rp) + : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary), + OpLoc(op), RParenLoc(rp) { + assert(ExprKind <= UETT_Last && "invalid enum value!"); UnaryExprOrTypeTraitExprBits.Kind = ExprKind; + assert(static_cast(ExprKind) == + UnaryExprOrTypeTraitExprBits.Kind && + "UnaryExprOrTypeTraitExprBits.Kind overflow!"); UnaryExprOrTypeTraitExprBits.IsType = true; Argument.Ty = TInfo; + setDependence(computeDependence(this)); } UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E, @@ -2403,7 +2548,12 @@ public: UnaryExprOrTypeTrait getKind() const { return static_cast(UnaryExprOrTypeTraitExprBits.Kind); } - void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;} + void setKind(UnaryExprOrTypeTrait K) { + assert(K <= UETT_Last && "invalid enum value!"); + UnaryExprOrTypeTraitExprBits.Kind = K; + assert(static_cast(K) == UnaryExprOrTypeTraitExprBits.Kind && + "UnaryExprOrTypeTraitExprBits.Kind overflow!"); + } bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; } QualType getArgumentType() const { @@ -2466,19 +2616,13 @@ class ArraySubscriptExpr : public Expr { bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); } public: - ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation rbracketloc) - : Expr(ArraySubscriptExprClass, t, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())) { + ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, + ExprObjectKind OK, SourceLocation rbracketloc) + : Expr(ArraySubscriptExprClass, t, VK, OK) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; - ArraySubscriptExprBits.RBracketLoc = rbracketloc; + ArrayOrMatrixSubscriptExprBits.RBracketLoc = rbracketloc; + setDependence(computeDependence(this)); } /// Create an empty array subscript expression. @@ -2514,10 +2658,10 @@ public: SourceLocation getEndLoc() const { return getRBracketLoc(); } SourceLocation getRBracketLoc() const { - return ArraySubscriptExprBits.RBracketLoc; + return ArrayOrMatrixSubscriptExprBits.RBracketLoc; } void setRBracketLoc(SourceLocation L) { - ArraySubscriptExprBits.RBracketLoc = L; + ArrayOrMatrixSubscriptExprBits.RBracketLoc = L; } SourceLocation getExprLoc() const LLVM_READONLY { @@ -2537,6 +2681,84 @@ public: } }; +/// MatrixSubscriptExpr - Matrix subscript expression for the MatrixType +/// extension. +/// MatrixSubscriptExpr can be either incomplete (only Base and RowIdx are set +/// so far, the type is IncompleteMatrixIdx) or complete (Base, RowIdx and +/// ColumnIdx refer to valid expressions). Incomplete matrix expressions only +/// exist during the initial construction of the AST. +class MatrixSubscriptExpr : public Expr { + enum { BASE, ROW_IDX, COLUMN_IDX, END_EXPR }; + Stmt *SubExprs[END_EXPR]; + +public: + MatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, QualType T, + SourceLocation RBracketLoc) + : Expr(MatrixSubscriptExprClass, T, Base->getValueKind(), + OK_MatrixComponent) { + SubExprs[BASE] = Base; + SubExprs[ROW_IDX] = RowIdx; + SubExprs[COLUMN_IDX] = ColumnIdx; + ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc; + setDependence(computeDependence(this)); + } + + /// Create an empty matrix subscript expression. + explicit MatrixSubscriptExpr(EmptyShell Shell) + : Expr(MatrixSubscriptExprClass, Shell) {} + + bool isIncomplete() const { + bool IsIncomplete = hasPlaceholderType(BuiltinType::IncompleteMatrixIdx); + assert((SubExprs[COLUMN_IDX] || IsIncomplete) && + "expressions without column index must be marked as incomplete"); + return IsIncomplete; + } + Expr *getBase() { return cast(SubExprs[BASE]); } + const Expr *getBase() const { return cast(SubExprs[BASE]); } + void setBase(Expr *E) { SubExprs[BASE] = E; } + + Expr *getRowIdx() { return cast(SubExprs[ROW_IDX]); } + const Expr *getRowIdx() const { return cast(SubExprs[ROW_IDX]); } + void setRowIdx(Expr *E) { SubExprs[ROW_IDX] = E; } + + Expr *getColumnIdx() { return cast_or_null(SubExprs[COLUMN_IDX]); } + const Expr *getColumnIdx() const { + assert(!isIncomplete() && + "cannot get the column index of an incomplete expression"); + return cast(SubExprs[COLUMN_IDX]); + } + void setColumnIdx(Expr *E) { SubExprs[COLUMN_IDX] = E; } + + SourceLocation getBeginLoc() const LLVM_READONLY { + return getBase()->getBeginLoc(); + } + + SourceLocation getEndLoc() const { return getRBracketLoc(); } + + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } + + SourceLocation getRBracketLoc() const { + return ArrayOrMatrixSubscriptExprBits.RBracketLoc; + } + void setRBracketLoc(SourceLocation L) { + ArrayOrMatrixSubscriptExprBits.RBracketLoc = L; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == MatrixSubscriptExprClass; + } + + // Iterators + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } +}; + /// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]). /// CallExpr itself represents a normal function call, e.g., "f(x, 2)", /// while its subclasses may represent alternative syntax that (semantically) @@ -2553,8 +2775,6 @@ class CallExpr : public Expr { /// the derived classes of CallExpr. SourceLocation RParenLoc; - void updateDependenciesFromArg(Expr *Arg); - // CallExpr store some data in trailing objects. However since CallExpr // is used a base of other expression classes we cannot use // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic @@ -2796,6 +3016,12 @@ public: /// a non-value-dependent constant parameter evaluating as false. bool isBuiltinAssumeFalse(const ASTContext &Ctx) const; + /// Used by Sema to implement MSVC-compatible delayed name lookup. + /// (Usually Exprs themselves should set dependence). + void markDependentForPostponedNameLookup() { + setDependence(getDependence() | ExprDependence::TypeValueInstantiation); + } + bool isCallToStdMove() const { const FunctionDecl *FD = getDirectCallee(); return getNumArgs() == 1 && FD && FD->isInStdNamespace() && @@ -3088,13 +3314,10 @@ class CompoundLiteralExpr : public Expr { public: CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, QualType T, ExprValueKind VK, Expr *init, bool fileScope) - : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, - tinfo->getType()->isDependentType(), - init->isValueDependent(), - (init->isInstantiationDependent() || - tinfo->getType()->isInstantiationDependentType()), - init->containsUnexpandedParameterPack()), - LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {} + : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary), + LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) { + setDependence(computeDependence(this)); + } /// Construct an empty compound literal. explicit CompoundLiteralExpr(EmptyShell Empty) @@ -3160,26 +3383,13 @@ class CastExpr : public Expr { protected: CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind, Expr *op, unsigned BasePathSize) - : Expr(SC, ty, VK, OK_Ordinary, - // Cast expressions are type-dependent if the type is - // dependent (C++ [temp.dep.expr]p3). - ty->isDependentType(), - // Cast expressions are value-dependent if the type is - // dependent or if the subexpression is value-dependent. - ty->isDependentType() || (op && op->isValueDependent()), - (ty->isInstantiationDependentType() || - (op && op->isInstantiationDependent())), - // An implicit cast expression doesn't (lexically) contain an - // unexpanded pack, even if its target type does. - ((SC != ImplicitCastExprClass && - ty->containsUnexpandedParameterPack()) || - (op && op->containsUnexpandedParameterPack()))), - Op(op) { + : Expr(SC, ty, VK, OK_Ordinary), Op(op) { CastExprBits.Kind = kind; CastExprBits.PartOfExplicitCast = false; CastExprBits.BasePathSize = BasePathSize; assert((CastExprBits.BasePathSize == BasePathSize) && "BasePathSize overflow!"); + setDependence(computeDependence(this)); assert(CastConsistency()); } @@ -3438,30 +3648,39 @@ class BinaryOperator : public Expr { public: typedef BinaryOperatorKind Opcode; - BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, FPOptions FPFeatures) - : Expr(BinaryOperatorClass, ResTy, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())) { - BinaryOperatorBits.Opc = opc; - BinaryOperatorBits.FPFeatures = FPFeatures.getInt(); - BinaryOperatorBits.OpLoc = opLoc; - SubExprs[LHS] = lhs; - SubExprs[RHS] = rhs; - assert(!isCompoundAssignmentOp() && - "Use CompoundAssignOperator for compound assignments"); +protected: + size_t offsetOfTrailingStorage() const; + + /// Return a pointer to the trailing FPOptions + FPOptionsOverride *getTrailingFPFeatures() { + assert(BinaryOperatorBits.HasFPFeatures); + return reinterpret_cast( + reinterpret_cast(this) + offsetOfTrailingStorage()); + } + const FPOptionsOverride *getTrailingFPFeatures() const { + assert(BinaryOperatorBits.HasFPFeatures); + return reinterpret_cast( + reinterpret_cast(this) + offsetOfTrailingStorage()); } + /// Build a binary operator, assuming that appropriate storage has been + /// allocated for the trailing objects when needed. + BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, + QualType ResTy, ExprValueKind VK, ExprObjectKind OK, + SourceLocation opLoc, FPOptionsOverride FPFeatures); + /// Construct an empty binary operator. explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) { BinaryOperatorBits.Opc = BO_Comma; } +public: + static BinaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures); + + static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs, + Opcode opc, QualType ResTy, ExprValueKind VK, + ExprObjectKind OK, SourceLocation opLoc, + FPOptionsOverride FPFeatures); SourceLocation getExprLoc() const { return getOperatorLoc(); } SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; } void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; } @@ -3602,47 +3821,65 @@ public: return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } - // Set the FP contractability status of this operator. Only meaningful for + /// Set and fetch the bit that shows whether FPFeatures needs to be + /// allocated in Trailing Storage + void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; } + bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; } + + /// Get FPFeatures from trailing storage + FPOptionsOverride getStoredFPFeatures() const { + assert(hasStoredFPFeatures()); + return *getTrailingFPFeatures(); + } + /// Set FPFeatures in trailing storage, used only by Serialization + void setStoredFPFeatures(FPOptionsOverride F) { + assert(BinaryOperatorBits.HasFPFeatures); + *getTrailingFPFeatures() = F; + } + + // Get the FP features status of this operator. Only meaningful for // operations on floating point types. - void setFPFeatures(FPOptions F) { - BinaryOperatorBits.FPFeatures = F.getInt(); + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { + if (BinaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures().applyOverrides(LO); + return FPOptions::defaultWithoutTrailingStorage(LO); } - FPOptions getFPFeatures() const { - return FPOptions(BinaryOperatorBits.FPFeatures); + // This is used in ASTImporter + FPOptionsOverride getFPFeatures(const LangOptions &LO) const { + if (BinaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures(); + return FPOptionsOverride(); } // Get the FP contractability status of this operator. Only meaningful for // operations on floating point types. - bool isFPContractableWithinStatement() const { - return getFPFeatures().allowFPContractWithinStatement(); + bool isFPContractableWithinStatement(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); } // Get the FENV_ACCESS status of this operator. Only meaningful for // operations on floating point types. - bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); } + bool isFEnvAccessOn(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).getAllowFEnvAccess(); + } protected: - BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, FPOptions FPFeatures, bool dead2) - : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())) { - BinaryOperatorBits.Opc = opc; - BinaryOperatorBits.FPFeatures = FPFeatures.getInt(); - BinaryOperatorBits.OpLoc = opLoc; - SubExprs[LHS] = lhs; - SubExprs[RHS] = rhs; - } + BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, + QualType ResTy, ExprValueKind VK, ExprObjectKind OK, + SourceLocation opLoc, FPOptionsOverride FPFeatures, + bool dead2); + /// Construct an empty BinaryOperator, SC is CompoundAssignOperator. BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { BinaryOperatorBits.Opc = BO_MulAssign; } + + /// Return the size in bytes needed for the trailing objects. + /// Used to allocate the right amount of storage. + static unsigned sizeOfTrailingObjects(bool HasFPFeatures) { + return HasFPFeatures * sizeof(FPOptionsOverride); + } }; /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep @@ -3654,22 +3891,33 @@ protected: class CompoundAssignOperator : public BinaryOperator { QualType ComputationLHSType; QualType ComputationResultType; -public: - CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, - ExprValueKind VK, ExprObjectKind OK, - QualType CompLHSType, QualType CompResultType, - SourceLocation OpLoc, FPOptions FPFeatures) - : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures, - true), - ComputationLHSType(CompLHSType), - ComputationResultType(CompResultType) { + + /// Construct an empty CompoundAssignOperator. + explicit CompoundAssignOperator(const ASTContext &C, EmptyShell Empty, + bool hasFPFeatures) + : BinaryOperator(CompoundAssignOperatorClass, Empty) {} + +protected: + CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, + QualType ResType, ExprValueKind VK, ExprObjectKind OK, + SourceLocation OpLoc, FPOptionsOverride FPFeatures, + QualType CompLHSType, QualType CompResultType) + : BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures, + true), + ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) { assert(isCompoundAssignmentOp() && "Only should be used for compound assignments"); } - /// Build an empty compound assignment operator expression. - explicit CompoundAssignOperator(EmptyShell Empty) - : BinaryOperator(CompoundAssignOperatorClass, Empty) { } +public: + static CompoundAssignOperator *CreateEmpty(const ASTContext &C, + bool hasFPFeatures); + + static CompoundAssignOperator * + Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, + FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(), + QualType CompResultType = QualType()); // The two computation types are the type the LHS is converted // to for the computation and the type of the result; the two are @@ -3685,6 +3933,12 @@ public: } }; +inline size_t BinaryOperator::offsetOfTrailingStorage() const { + assert(BinaryOperatorBits.HasFPFeatures); + return isa(this) ? sizeof(CompoundAssignOperator) + : sizeof(BinaryOperator); +} + /// AbstractConditionalOperator - An abstract base class for /// ConditionalOperator and BinaryConditionalOperator. class AbstractConditionalOperator : public Expr { @@ -3692,14 +3946,10 @@ class AbstractConditionalOperator : public Expr { friend class ASTStmtReader; protected: - AbstractConditionalOperator(StmtClass SC, QualType T, - ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, bool ID, - bool ContainsUnexpandedParameterPack, - SourceLocation qloc, + AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK, + ExprObjectKind OK, SourceLocation qloc, SourceLocation cloc) - : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack), - QuestionLoc(qloc), ColonLoc(cloc) {} + : Expr(SC, T, VK, OK), QuestionLoc(qloc), ColonLoc(cloc) {} AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { } @@ -3738,26 +3988,12 @@ public: ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, SourceLocation CLoc, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK) - : AbstractConditionalOperator( - ConditionalOperatorClass, t, VK, OK, - // The type of the conditional operator depends on the type - // of the conditional to support the GCC vector conditional - // extension. Additionally, [temp.dep.expr] does specify state that - // this should be dependent on ALL sub expressions. - (cond->isTypeDependent() || lhs->isTypeDependent() || - rhs->isTypeDependent()), - (cond->isValueDependent() || lhs->isValueDependent() || - rhs->isValueDependent()), - (cond->isInstantiationDependent() || - lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (cond->containsUnexpandedParameterPack() || - lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack()), - QLoc, CLoc) { + : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc, + CLoc) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; + setDependence(computeDependence(this)); } /// Build an empty conditional operator. @@ -3822,20 +4058,15 @@ public: Expr *cond, Expr *lhs, Expr *rhs, SourceLocation qloc, SourceLocation cloc, QualType t, ExprValueKind VK, ExprObjectKind OK) - : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, - (common->isTypeDependent() || rhs->isTypeDependent()), - (common->isValueDependent() || rhs->isValueDependent()), - (common->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (common->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack()), - qloc, cloc), - OpaqueValue(opaqueValue) { + : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, + qloc, cloc), + OpaqueValue(opaqueValue) { SubExprs[COMMON] = common; SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value"); + setDependence(computeDependence(this)); } /// Build an empty conditional operator. @@ -3913,9 +4144,10 @@ class AddrLabelExpr : public Expr { public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, QualType t) - : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false, - false), - AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary), AmpAmpLoc(AALoc), + LabelLoc(LLoc), Label(L) { + setDependence(ExprDependence::None); + } /// Build an empty address of a label expression. explicit AddrLabelExpr(EmptyShell Empty) @@ -3957,12 +4189,9 @@ class StmtExpr : public Expr { public: StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParenLoc, SourceLocation RParenLoc, unsigned TemplateDepth) - : // We treat a statement-expression in a dependent context as - // always being value- and instantiation-dependent. This matches the - // behavior of lambda-expressions and GCC. - Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, T->isDependentType(), - TemplateDepth != 0, TemplateDepth != 0, false), - SubStmt(SubStmt), LParenLoc(LParenLoc), RParenLoc(RParenLoc) { + : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary), SubStmt(SubStmt), + LParenLoc(LParenLoc), RParenLoc(RParenLoc) { + setDependence(computeDependence(this, TemplateDepth)); // FIXME: A templated statement expression should have an associated // DeclContext so that nested declarations always have a dependent context. StmtExprBits.TemplateDepth = TemplateDepth; @@ -4081,17 +4310,13 @@ private: explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {} public: - ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation BuiltinLoc, SourceLocation RParenLoc) - : Expr(ConvertVectorExprClass, DstType, VK, OK, - DstType->isDependentType(), - DstType->isDependentType() || SrcExpr->isValueDependent(), - (DstType->isInstantiationDependentType() || - SrcExpr->isInstantiationDependent()), - (DstType->containsUnexpandedParameterPack() || - SrcExpr->containsUnexpandedParameterPack())), - SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + ConvertVectorExpr(Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, + ExprValueKind VK, ExprObjectKind OK, + SourceLocation BuiltinLoc, SourceLocation RParenLoc) + : Expr(ConvertVectorExprClass, DstType, VK, OK), SrcExpr(SrcExpr), + TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) { + setDependence(computeDependence(this)); + } /// getSrcExpr - Return the Expr to be converted. Expr *getSrcExpr() const { return cast(SrcExpr); } @@ -4139,22 +4364,17 @@ class ChooseExpr : public Expr { SourceLocation BuiltinLoc, RParenLoc; bool CondIsTrue; public: - ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, - QualType t, ExprValueKind VK, ExprObjectKind OK, - SourceLocation RP, bool condIsTrue, - bool TypeDependent, bool ValueDependent) - : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, - (cond->isInstantiationDependent() || - lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (cond->containsUnexpandedParameterPack() || - lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())), - BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) { - SubExprs[COND] = cond; - SubExprs[LHS] = lhs; - SubExprs[RHS] = rhs; - } + ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, + bool condIsTrue) + : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP), + CondIsTrue(condIsTrue) { + SubExprs[COND] = cond; + SubExprs[LHS] = lhs; + SubExprs[RHS] = rhs; + + setDependence(computeDependence(this)); + } /// Build an empty __builtin_choose_expr. explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { } @@ -4219,9 +4439,9 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false, - false), - TokenLoc(Loc) { } + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary), TokenLoc(Loc) { + setDependence(ExprDependence::None); + } /// Build an empty GNU __null expression. explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { } @@ -4254,12 +4474,10 @@ class VAArgExpr : public Expr { public: VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo, SourceLocation RPLoc, QualType t, bool IsMS) - : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(), - false, (TInfo->getType()->isInstantiationDependentType() || - e->isInstantiationDependent()), - (TInfo->getType()->containsUnexpandedParameterPack() || - e->containsUnexpandedParameterPack())), - Val(e), TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {} + : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary), Val(e), + TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) { + setDependence(computeDependence(this)); + } /// Create an empty __builtin_va_arg expression. explicit VAArgExpr(EmptyShell Empty) @@ -4468,13 +4686,8 @@ public: assert(Init < getNumInits() && "Initializer access out of range!"); InitExprs[Init] = expr; - if (expr) { - ExprBits.TypeDependent |= expr->isTypeDependent(); - ExprBits.ValueDependent |= expr->isValueDependent(); - ExprBits.InstantiationDependent |= expr->isInstantiationDependent(); - ExprBits.ContainsUnexpandedParameterPack |= - expr->containsUnexpandedParameterPack(); - } + if (expr) + setDependence(getDependence() | expr->getDependence()); } /// Reserve space for some number of initializers. @@ -4943,8 +5156,9 @@ public: class NoInitExpr : public Expr { public: explicit NoInitExpr(QualType ty) - : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, ty->isInstantiationDependentType(), false) { } + : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary) { + setDependence(computeDependence(this)); + } explicit NoInitExpr(EmptyShell Empty) : Expr(NoInitExprClass, Empty) { } @@ -5038,12 +5252,10 @@ class ArrayInitLoopExpr : public Expr { public: explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit) - : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false, - CommonInit->isValueDependent() || ElementInit->isValueDependent(), - T->isInstantiationDependentType(), - CommonInit->containsUnexpandedParameterPack() || - ElementInit->containsUnexpandedParameterPack()), - SubExprs{CommonInit, ElementInit} {} + : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary), + SubExprs{CommonInit, ElementInit} { + setDependence(computeDependence(this)); + } /// Get the common subexpression shared by all initializations (the source /// array). @@ -5091,8 +5303,9 @@ class ArrayInitIndexExpr : public Expr { public: explicit ArrayInitIndexExpr(QualType T) - : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary, - false, false, false, false) {} + : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary) { + setDependence(ExprDependence::None); + } static bool classof(const Stmt *S) { return S->getStmtClass() == ArrayInitIndexExprClass; @@ -5123,8 +5336,9 @@ public: class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) - : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, ty->isInstantiationDependentType(), false) { } + : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary) { + setDependence(computeDependence(this)); + } /// Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -5283,10 +5497,9 @@ class GenericSelectionExpr final template class AssociationTy { friend class GenericSelectionExpr; template friend class AssociationIteratorTy; - using ExprPtrTy = - typename std::conditional::type; - using TSIPtrTy = typename std::conditional::type; + using ExprPtrTy = std::conditional_t; + using TSIPtrTy = + std::conditional_t; ExprPtrTy E; TSIPtrTy TSI; bool Selected; @@ -5328,10 +5541,9 @@ class GenericSelectionExpr final // const Association &Assoc = *It++; // Oops, Assoc is dangling. using BaseTy = typename AssociationIteratorTy::iterator_facade_base; using StmtPtrPtrTy = - typename std::conditional::type; - using TSIPtrPtrTy = - typename std::conditional::type; + std::conditional_t; + using TSIPtrPtrTy = std::conditional_t; StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped. TSIPtrPtrTy TSI; // Kept in sync with E. unsigned Offset = 0, SelectedOffset = 0; @@ -5528,12 +5740,11 @@ class ExtVectorElementExpr : public Expr { public: ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base, IdentifierInfo &accessor, SourceLocation loc) - : Expr(ExtVectorElementExprClass, ty, VK, - (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), - base->isTypeDependent(), base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), Accessor(&accessor), AccessorLoc(loc) {} + : Expr(ExtVectorElementExprClass, ty, VK, + (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent)), + Base(base), Accessor(&accessor), AccessorLoc(loc) { + setDependence(computeDependence(this)); + } /// Build an empty vector element expression. explicit ExtVectorElementExpr(EmptyShell Empty) @@ -5587,11 +5798,9 @@ protected: BlockDecl *TheBlock; public: BlockExpr(BlockDecl *BD, QualType ty) - : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, - ty->isDependentType(), ty->isDependentType(), - ty->isInstantiationDependentType() || BD->isDependentContext(), - false), - TheBlock(BD) {} + : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary), TheBlock(BD) { + setDependence(computeDependence(this)); + } /// Build an empty block expression. explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { } @@ -5655,17 +5864,13 @@ private: explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {} public: - AsTypeExpr(Expr* SrcExpr, QualType DstType, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation BuiltinLoc, SourceLocation RParenLoc) - : Expr(AsTypeExprClass, DstType, VK, OK, - DstType->isDependentType(), - DstType->isDependentType() || SrcExpr->isValueDependent(), - (DstType->isInstantiationDependentType() || - SrcExpr->isInstantiationDependent()), - (DstType->containsUnexpandedParameterPack() || - SrcExpr->containsUnexpandedParameterPack())), - SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + AsTypeExpr(Expr *SrcExpr, QualType DstType, ExprValueKind VK, + ExprObjectKind OK, SourceLocation BuiltinLoc, + SourceLocation RParenLoc) + : Expr(AsTypeExprClass, DstType, VK, OK), SrcExpr(SrcExpr), + BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) { + setDependence(computeDependence(this)); + } /// getSrcExpr - Return the Expr to be converted. Expr *getSrcExpr() const { return cast(SrcExpr); } @@ -5982,14 +6187,15 @@ public: /// TypoExpr - Internal placeholder for expressions where typo correction /// still needs to be performed and/or an error diagnostic emitted. class TypoExpr : public Expr { + // The location for the typo name. + SourceLocation TypoLoc; + public: - TypoExpr(QualType T) - : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary, - /*isTypeDependent*/ true, - /*isValueDependent*/ true, - /*isInstantiationDependent*/ true, - /*containsUnexpandedParameterPack*/ false) { + TypoExpr(QualType T, SourceLocation TypoLoc) + : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary), TypoLoc(TypoLoc) { assert(T->isDependentType() && "TypoExpr given a non-dependent type"); + setDependence(ExprDependence::TypeValueInstantiation | + ExprDependence::Error); } child_range children() { @@ -5999,14 +6205,88 @@ public: return const_child_range(const_child_iterator(), const_child_iterator()); } - SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); } - SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); } + SourceLocation getBeginLoc() const LLVM_READONLY { return TypoLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return TypoLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == TypoExprClass; } }; + +/// Frontend produces RecoveryExprs on semantic errors that prevent creating +/// other well-formed expressions. E.g. when type-checking of a binary operator +/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose +/// to produce a recovery expression storing left and right operands. +/// +/// RecoveryExpr does not have any semantic meaning in C++, it is only useful to +/// preserve expressions in AST that would otherwise be dropped. It captures +/// subexpressions of some expression that we could not construct and source +/// range covered by the expression. +/// +/// By default, RecoveryExpr uses dependence-bits to take advantage of existing +/// machinery to deal with dependent code in C++, e.g. RecoveryExpr is preserved +/// in `decltype()` as part of the `DependentDecltypeType`. In +/// addition to that, clang does not report most errors on dependent +/// expressions, so we get rid of bogus errors for free. However, note that +/// unlike other dependent expressions, RecoveryExpr can be produced in +/// non-template contexts. +/// +/// We will preserve the type in RecoveryExpr when the type is known, e.g. +/// preserving the return type for a broken non-overloaded function call, a +/// overloaded call where all candidates have the same return type. In this +/// case, the expression is not type-dependent (unless the known type is itself +/// dependent) +/// +/// 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 { +public: + static RecoveryExpr *Create(ASTContext &Ctx, QualType T, + SourceLocation BeginLoc, SourceLocation EndLoc, + ArrayRef SubExprs); + static RecoveryExpr *CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs); + + ArrayRef subExpressions() { + auto *B = getTrailingObjects(); + return llvm::makeArrayRef(B, B + NumExprs); + } + + ArrayRef subExpressions() const { + return const_cast(this)->subExpressions(); + } + + child_range children() { + Stmt **B = reinterpret_cast(getTrailingObjects()); + return child_range(B, B + NumExprs); + } + + SourceLocation getBeginLoc() const { return BeginLoc; } + SourceLocation getEndLoc() const { return EndLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == RecoveryExprClass; + } + +private: + RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc, + SourceLocation EndLoc, ArrayRef SubExprs); + RecoveryExpr(EmptyShell Empty, unsigned NumSubExprs) + : Expr(RecoveryExprClass, Empty), NumExprs(NumSubExprs) {} + + size_t numTrailingObjects(OverloadToken) const { return NumExprs; } + + SourceLocation BeginLoc, EndLoc; + unsigned NumExprs; + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; +}; + } // end namespace clang #endif // LLVM_CLANG_AST_EXPR_H diff --git a/gnu/llvm/clang/include/clang/AST/ExprCXX.h b/gnu/llvm/clang/include/clang/AST/ExprCXX.h index cea360d12e9..6f0b68479b9 100644 --- a/gnu/llvm/clang/include/clang/AST/ExprCXX.h +++ b/gnu/llvm/clang/include/clang/AST/ExprCXX.h @@ -14,15 +14,19 @@ #ifndef LLVM_CLANG_AST_EXPRCXX_H #define LLVM_CLANG_AST_EXPRCXX_H +#include "clang/AST/ASTConcept.h" +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/AST/UnresolvedSet.h" @@ -80,6 +84,7 @@ 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. @@ -88,7 +93,7 @@ class CXXOperatorCallExpr final : public CallExpr { CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef Args, QualType Ty, ExprValueKind VK, - SourceLocation OperatorLoc, FPOptions FPFeatures, + SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL); CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty); @@ -97,7 +102,7 @@ public: static CXXOperatorCallExpr * Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef Args, QualType Ty, ExprValueKind VK, - SourceLocation OperatorLoc, FPOptions FPFeatures, + SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL = NotADL); static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx, @@ -118,6 +123,22 @@ public: } bool isAssignmentOp() const { return isAssignmentOp(getOperator()); } + static bool isComparisonOp(OverloadedOperatorKind Opc) { + switch (Opc) { + case OO_EqualEqual: + case OO_ExclaimEqual: + case OO_Greater: + case OO_GreaterEqual: + case OO_Less: + case OO_LessEqual: + case OO_Spaceship: + return true; + default: + return false; + } + } + bool isComparisonOp() const { return isComparisonOp(getOperator()); } + /// Is this written as an infix binary operator? bool isInfixBinaryOp() const; @@ -144,20 +165,10 @@ public: return T->getStmtClass() == CXXOperatorCallExprClass; } - // Set the FP contractability status of this operator. Only meaningful for - // operations on floating point types. - void setFPFeatures(FPOptions F) { - CXXOperatorCallExprBits.FPFeatures = F.getInt(); - } - FPOptions getFPFeatures() const { - return FPOptions(CXXOperatorCallExprBits.FPFeatures); - } - - // Get the FP contractability status of this operator. Only meaningful for + // Set the FPFeatures status of this operator. Only meaningful for // operations on floating point types. - bool isFPContractableWithinStatement() const { - return getFPFeatures().allowFPContractWithinStatement(); - } + void setFPFeatures(FPOptionsOverride F) { Overrides = F; } + FPOptionsOverride getFPFeatures() const { return Overrides; } }; /// Represents a call to a member function that @@ -279,12 +290,10 @@ class CXXRewrittenBinaryOperator : public Expr { public: CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed) : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(), - SemanticForm->getValueKind(), SemanticForm->getObjectKind(), - SemanticForm->isTypeDependent(), SemanticForm->isValueDependent(), - SemanticForm->isInstantiationDependent(), - SemanticForm->containsUnexpandedParameterPack()), + SemanticForm->getValueKind(), SemanticForm->getObjectKind()), SemanticForm(SemanticForm) { CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed; + setDependence(computeDependence(this)); } CXXRewrittenBinaryOperator(EmptyShell Empty) : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {} @@ -349,7 +358,8 @@ public: /// This abstract class is inherited by all of the classes /// representing "named" casts: CXXStaticCastExpr for \c static_cast, /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for -/// reinterpret_cast, and CXXConstCastExpr for \c const_cast. +/// reinterpret_cast, CXXConstCastExpr for \c const_cast and +/// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL). class CXXNamedCastExpr : public ExplicitCastExpr { private: // the location of the casting op @@ -395,6 +405,7 @@ public: case CXXDynamicCastExprClass: case CXXReinterpretCastExprClass: case CXXConstCastExprClass: + case CXXAddrspaceCastExprClass: return true; default: return false; @@ -552,6 +563,41 @@ public: } }; +/// A C++ addrspace_cast expression (currently only enabled for OpenCL). +/// +/// This expression node represents a cast between pointers to objects in +/// different address spaces e.g., +/// \c addrspace_cast(PtrToGenericInt). +/// +/// A addrspace_cast can cast address space type qualifiers but does not change +/// the underlying value. +class CXXAddrspaceCastExpr final + : public CXXNamedCastExpr, + private llvm::TrailingObjects { + CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op, + TypeSourceInfo *writtenTy, SourceLocation l, + SourceLocation RParenLoc, SourceRange AngleBrackets) + : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0, + writtenTy, l, RParenLoc, AngleBrackets) {} + + explicit CXXAddrspaceCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {} + +public: + friend class CastExpr; + friend TrailingObjects; + + static CXXAddrspaceCastExpr * + Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, + Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, + SourceLocation RParenLoc, SourceRange AngleBrackets); + static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXAddrspaceCastExprClass; + } +}; + /// A call to a literal operator (C++11 [over.literal]) /// written as a user-defined literal (C++11 [lit.ext]). /// @@ -645,10 +691,10 @@ public: class CXXBoolLiteralExpr : public Expr { public: CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc) - : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false) { + : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary) { CXXBoolLiteralExprBits.Value = Val; CXXBoolLiteralExprBits.Loc = Loc; + setDependence(ExprDependence::None); } explicit CXXBoolLiteralExpr(EmptyShell Empty) @@ -683,9 +729,9 @@ public: class CXXNullPtrLiteralExpr : public Expr { public: CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc) - : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, - false, false, false) { + : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary) { CXXNullPtrLiteralExprBits.Loc = Loc; + setDependence(ExprDependence::None); } explicit CXXNullPtrLiteralExpr(EmptyShell Empty) @@ -723,11 +769,10 @@ public: friend class ASTStmtReader; CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) - : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, - Ty->isDependentType(), SubExpr->isValueDependent(), - SubExpr->isInstantiationDependent(), - SubExpr->containsUnexpandedParameterPack()), - SubExpr(SubExpr) {} + : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary), + SubExpr(SubExpr) { + setDependence(computeDependence(this)); + } Expr *getSubExpr() { return static_cast(SubExpr); } const Expr *getSubExpr() const { return static_cast(SubExpr); } @@ -762,32 +807,24 @@ public: /// /// This represents code like \c typeid(int) or \c typeid(*objPtr) class CXXTypeidExpr : public Expr { + friend class ASTStmtReader; + private: llvm::PointerUnion Operand; SourceRange Range; public: CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, - // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, - // typeid is value-dependent if the type or expression are - // dependent - Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) {} + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Range(R) { + setDependence(computeDependence(this)); + } CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, - // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, - // typeid is value-dependent if the type or expression are - // dependent - Operand->isTypeDependent() || Operand->isValueDependent(), - Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) {} + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Range(R) { + setDependence(computeDependence(this)); + } CXXTypeidExpr(EmptyShell Empty, bool isExpr) : Expr(CXXTypeidExprClass, Empty) { @@ -812,22 +849,11 @@ public: assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); return Operand.get(); } - - void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { - assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); - Operand = TSI; - } - Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); return static_cast(Operand.get()); } - void setExprOperand(Expr *E) { - assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); - Operand = E; - } - SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -872,15 +898,12 @@ public: MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, QualType ty, ExprValueKind VK, - NestedNameSpecifierLoc qualifierLoc, - SourceLocation nameLoc) - : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary, - /*type-dependent*/ false, baseExpr->isValueDependent(), - baseExpr->isInstantiationDependent(), - baseExpr->containsUnexpandedParameterPack()), - BaseExpr(baseExpr), TheDecl(decl), - MemberLoc(nameLoc), IsArrow(isArrow), - QualifierLoc(qualifierLoc) {} + NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc) + : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr), + TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow), + QualifierLoc(qualifierLoc) { + setDependence(computeDependence(this)); + } MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} @@ -948,12 +971,11 @@ class MSPropertySubscriptExpr : public Expr { public: MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK, ExprObjectKind OK, SourceLocation RBracketLoc) - : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(), - Idx->isValueDependent(), Idx->isInstantiationDependent(), - Idx->containsUnexpandedParameterPack()), + : Expr(MSPropertySubscriptExprClass, Ty, VK, OK), RBracketLoc(RBracketLoc) { SubExprs[BASE_EXPR] = Base; SubExprs[IDX_EXPR] = Idx; + setDependence(computeDependence(this)); } /// Create an empty array subscript expression. @@ -998,25 +1020,26 @@ public: /// /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) class CXXUuidofExpr : public Expr { + friend class ASTStmtReader; + private: llvm::PointerUnion Operand; - StringRef UuidStr; + MSGuidDecl *Guid; SourceRange Range; public: - CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr, + CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, - Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), UuidStr(UuidStr), Range(R) {} - - CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, - Operand->isTypeDependent(), Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), UuidStr(UuidStr), Range(R) {} + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Guid(Guid), Range(R) { + setDependence(computeDependence(this)); + } + + CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R) + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Guid(Guid), Range(R) { + setDependence(computeDependence(this)); + } CXXUuidofExpr(EmptyShell Empty, bool isExpr) : Expr(CXXUuidofExprClass, Empty) { @@ -1037,24 +1060,12 @@ public: assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); return Operand.get(); } - - void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { - assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); - Operand = TSI; - } - Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)"); return static_cast(Operand.get()); } - void setExprOperand(Expr *E) { - assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)"); - Operand = E; - } - - void setUuidStr(StringRef US) { UuidStr = US; } - StringRef getUuidStr() const { return UuidStr; } + MSGuidDecl *getGuidDecl() const { return Guid; } SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } @@ -1097,14 +1108,10 @@ public: class CXXThisExpr : public Expr { public: CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit) - : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary, - // 'this' is type-dependent if the class type of the enclosing - // member function is dependent (C++ [temp.dep.expr]p2) - Ty->isDependentType(), Ty->isDependentType(), - Ty->isInstantiationDependentType(), - /*ContainsUnexpandedParameterPack=*/false) { + : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary) { CXXThisExprBits.IsImplicit = IsImplicit; CXXThisExprBits.Loc = L; + setDependence(computeDependence(this)); } CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} @@ -1150,12 +1157,10 @@ public: // null if not present. CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc, bool IsThrownVariableInScope) - : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - Operand && Operand->isInstantiationDependent(), - Operand && Operand->containsUnexpandedParameterPack()), - Operand(Operand) { + : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand) { CXXThrowExprBits.ThrowLoc = Loc; CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope; + setDependence(computeDependence(this)); } CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} @@ -1209,16 +1214,16 @@ class CXXDefaultArgExpr final : public Expr { DeclContext *UsedContext; CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param, - DeclContext *UsedContext) + DeclContext *UsedContext) : Expr(SC, Param->hasUnparsedDefaultArg() ? Param->getType().getNonReferenceType() : Param->getDefaultArg()->getType(), Param->getDefaultArg()->getValueKind(), - Param->getDefaultArg()->getObjectKind(), false, false, false, - false), + Param->getDefaultArg()->getObjectKind()), Param(Param), UsedContext(UsedContext) { CXXDefaultArgExprBits.Loc = Loc; + setDependence(ExprDependence::None); } public: @@ -1374,13 +1379,12 @@ class CXXBindTemporaryExpr : public Expr { CXXTemporary *Temp = nullptr; Stmt *SubExpr = nullptr; - CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr) - : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), - VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), - SubExpr->isValueDependent(), - SubExpr->isInstantiationDependent(), - SubExpr->containsUnexpandedParameterPack()), - Temp(temp), SubExpr(SubExpr) {} + CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr) + : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue, + OK_Ordinary), + Temp(temp), SubExpr(SubExpr) { + setDependence(computeDependence(this)); + } public: CXXBindTemporaryExpr(EmptyShell Empty) @@ -1631,12 +1635,12 @@ public: CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, bool InheritedFromVirtualBase) - : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false, - false, false, false), + : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary), Constructor(Ctor), Loc(Loc), ConstructsVirtualBase(ConstructsVirtualBase), InheritedFromVirtualBase(InheritedFromVirtualBase) { assert(!T->isDependentType()); + setDependence(ExprDependence::None); } /// Construct an empty C++ inheriting construction expression. @@ -1817,26 +1821,14 @@ Stmt **CXXConstructExpr::getTrailingArgs() { /// and which can never occur implicitly. class LambdaExpr final : public Expr, private llvm::TrailingObjects { + // LambdaExpr has some data stored in LambdaExprBits. + /// The source range that covers the lambda introducer ([...]). SourceRange IntroducerRange; /// The source location of this lambda's capture-default ('=' or '&'). SourceLocation CaptureDefaultLoc; - /// The number of captures. - unsigned NumCaptures : 16; - - /// The default capture kind, which is a value of type - /// LambdaCaptureDefault. - unsigned CaptureDefault : 2; - - /// Whether this lambda had an explicit parameter list vs. an - /// implicit (and empty) parameter list. - unsigned ExplicitParams : 1; - - /// Whether this lambda had the result type explicitly specified. - unsigned ExplicitResultType : 1; - /// The location of the closing brace ('}') that completes /// the lambda. /// @@ -1850,23 +1842,18 @@ class LambdaExpr final : public Expr, /// Construct a lambda expression. LambdaExpr(QualType T, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, - SourceLocation CaptureDefaultLoc, ArrayRef Captures, - bool ExplicitParams, bool ExplicitResultType, - ArrayRef CaptureInits, SourceLocation ClosingBrace, - bool ContainsUnexpandedParameterPack); + SourceLocation CaptureDefaultLoc, bool ExplicitParams, + bool ExplicitResultType, ArrayRef CaptureInits, + SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); /// Construct an empty lambda expression. - LambdaExpr(EmptyShell Empty, unsigned NumCaptures) - : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures), - CaptureDefault(LCD_None), ExplicitParams(false), - ExplicitResultType(false) { - getStoredStmts()[NumCaptures] = nullptr; - } + LambdaExpr(EmptyShell Empty, unsigned NumCaptures); Stmt **getStoredStmts() { return getTrailingObjects(); } - Stmt *const *getStoredStmts() const { return getTrailingObjects(); } + void initBodyIfNeeded() const; + public: friend class ASTStmtReader; friend class ASTStmtWriter; @@ -1876,9 +1863,9 @@ public: static LambdaExpr * Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc, - ArrayRef Captures, bool ExplicitParams, - bool ExplicitResultType, ArrayRef CaptureInits, - SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); + bool ExplicitParams, bool ExplicitResultType, + ArrayRef CaptureInits, SourceLocation ClosingBrace, + bool ContainsUnexpandedParameterPack); /// Construct a new lambda expression that will be deserialized from /// an external source. @@ -1887,13 +1874,11 @@ public: /// Determine the default capture kind for this lambda. LambdaCaptureDefault getCaptureDefault() const { - return static_cast(CaptureDefault); + return static_cast(LambdaExprBits.CaptureDefault); } /// Retrieve the location of this lambda's capture-default, if any. - SourceLocation getCaptureDefaultLoc() const { - return CaptureDefaultLoc; - } + SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; } /// Determine whether one of this lambda's captures is an init-capture. bool isInitCapture(const LambdaCapture *Capture) const; @@ -1916,7 +1901,7 @@ public: capture_iterator capture_end() const; /// Determine the number of captures in this lambda. - unsigned capture_size() const { return NumCaptures; } + unsigned capture_size() const { return LambdaExprBits.NumCaptures; } /// Retrieve this lambda's explicit captures. capture_range explicit_captures() const; @@ -1946,6 +1931,7 @@ public: /// Const iterator that walks over the capture initialization /// arguments. + /// FIXME: This interface is prone to being used incorrectly. using const_capture_init_iterator = Expr *const *; /// Retrieve the initialization expressions for this lambda's captures. @@ -1973,13 +1959,13 @@ public: /// Retrieve the iterator pointing one past the last /// initialization argument for this lambda expression. capture_init_iterator capture_init_end() { - return capture_init_begin() + NumCaptures; + return capture_init_begin() + capture_size(); } /// Retrieve the iterator pointing one past the last /// initialization argument for this lambda expression. const_capture_init_iterator capture_init_end() const { - return capture_init_begin() + NumCaptures; + return capture_init_begin() + capture_size(); } /// Retrieve the source range covering the lambda introducer, @@ -2013,8 +1999,20 @@ public: /// Whether this is a generic lambda. bool isGenericLambda() const { return getTemplateParameterList(); } - /// Retrieve the body of the lambda. - CompoundStmt *getBody() const; + /// Retrieve the body of the lambda. This will be most of the time + /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping + /// a \p CompoundStmt. Note that unlike functions, lambda-expressions + /// cannot have a function-try-block. + Stmt *getBody() const; + + /// Retrieve the \p CompoundStmt representing the body of the lambda. + /// This is a convenience function for callers who do not need + /// to handle node(s) which may wrap a \p CompoundStmt. + const CompoundStmt *getCompoundStmtBody() const; + CompoundStmt *getCompoundStmtBody() { + const auto *ConstThis = this; + return const_cast(ConstThis->getCompoundStmtBody()); + } /// Determine whether the lambda is mutable, meaning that any /// captures values can be modified. @@ -2022,10 +2020,12 @@ public: /// Determine whether this lambda has an explicit parameter /// list vs. an implicit (empty) parameter list. - bool hasExplicitParameters() const { return ExplicitParams; } + bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; } /// Whether this lambda had its result type explicitly specified. - bool hasExplicitResultType() const { return ExplicitResultType; } + bool hasExplicitResultType() const { + return LambdaExprBits.ExplicitResultType; + } static bool classof(const Stmt *T) { return T->getStmtClass() == LambdaExprClass; @@ -2037,15 +2037,9 @@ public: SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; } - child_range children() { - // Includes initialization exprs plus body stmt - return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); - } - - const_child_range children() const { - return const_child_range(getStoredStmts(), - getStoredStmts() + NumCaptures + 1); - } + /// Includes the captures and the body of the lambda. + child_range children(); + const_child_range children() const; }; /// An expression "T()" which creates a value-initialized rvalue of type @@ -2060,11 +2054,10 @@ public: /// expression. CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, SourceLocation RParenLoc) - : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false, - false, Type->isInstantiationDependentType(), - Type->containsUnexpandedParameterPack()), + : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary), TypeInfo(TypeInfo) { CXXScalarValueInitExprBits.RParenLoc = RParenLoc; + setDependence(computeDependence(this)); } explicit CXXScalarValueInitExpr(EmptyShell Shell) @@ -2369,15 +2362,14 @@ public: CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm, bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize, FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc) - : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false, - Arg->isValueDependent(), Arg->isInstantiationDependent(), - Arg->containsUnexpandedParameterPack()), + : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary), OperatorDelete(OperatorDelete), Argument(Arg) { CXXDeleteExprBits.GlobalDelete = GlobalDelete; CXXDeleteExprBits.ArrayForm = ArrayForm; CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten; CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; CXXDeleteExprBits.Loc = Loc; + setDependence(computeDependence(this)); } explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} @@ -2735,15 +2727,15 @@ public: friend class ASTStmtReader; ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, - TypeSourceInfo *queried, uint64_t value, - Expr *dimension, SourceLocation rparen, QualType ty) - : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, - false, queried->getType()->isDependentType(), - (queried->getType()->isInstantiationDependentType() || - (dimension && dimension->isInstantiationDependent())), - queried->getType()->containsUnexpandedParameterPack()), - ATT(att), Value(value), Dimension(dimension), - Loc(loc), RParen(rparen), QueriedType(queried) {} + TypeSourceInfo *queried, uint64_t value, Expr *dimension, + SourceLocation rparen, QualType ty) + : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary), ATT(att), + Value(value), Dimension(dimension), Loc(loc), RParen(rparen), + QueriedType(queried) { + assert(att <= ATT_Last && "invalid enum value!"); + assert(static_cast(att) == ATT && "ATT overflow!"); + setDependence(computeDependence(this)); + } explicit ArrayTypeTraitExpr(EmptyShell Empty) : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} @@ -2801,17 +2793,15 @@ class ExpressionTraitExpr : public Expr { public: friend class ASTStmtReader; - ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, - Expr *queried, bool value, - SourceLocation rparen, QualType resultType) - : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary, - false, // Not type-dependent - // Value-dependent if the argument is type-dependent. - queried->isTypeDependent(), - queried->isInstantiationDependent(), - queried->containsUnexpandedParameterPack()), + ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, + bool value, SourceLocation rparen, QualType resultType) + : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary), ET(et), Value(value), Loc(loc), RParen(rparen), - QueriedExpression(queried) {} + QueriedExpression(queried) { + assert(et <= ET_Last && "invalid enum value!"); + assert(static_cast(et) == ET && "ET overflow!"); + setDependence(computeDependence(this)); + } explicit ExpressionTraitExpr(EmptyShell Empty) : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} @@ -3305,13 +3295,15 @@ public: /// literal is the extent of the enclosing scope. class ExprWithCleanups final : public FullExpr, - private llvm::TrailingObjects { + private llvm::TrailingObjects< + ExprWithCleanups, + llvm::PointerUnion> { public: /// The type of objects that are kept in the cleanup. - /// It's useful to remember the set of blocks; we could also - /// remember the set of temporaries, but there's currently - /// no need. - using CleanupObject = BlockDecl *; + /// It's useful to remember the set of blocks and block-scoped compound + /// literals; we could also remember the set of temporaries, but there's + /// currently no need. + using CleanupObject = llvm::PointerUnion; private: friend class ASTStmtReader; @@ -3964,13 +3956,10 @@ class CXXNoexceptExpr : public Expr { public: CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, SourceLocation Keyword, SourceLocation RParen) - : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, - /*TypeDependent*/ false, - /*ValueDependent*/ Val == CT_Dependent, - Val == CT_Dependent || Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), + : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand), Range(Keyword, RParen) { CXXNoexceptExprBits.Value = Val == CT_Cannot; + setDependence(computeDependence(this, Val)); } CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {} @@ -4031,12 +4020,12 @@ public: PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc, Optional NumExpansions) : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), - Pattern->getObjectKind(), /*TypeDependent=*/true, - /*ValueDependent=*/true, /*InstantiationDependent=*/true, - /*ContainsUnexpandedParameterPack=*/false), + Pattern->getObjectKind()), EllipsisLoc(EllipsisLoc), NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), - Pattern(Pattern) {} + Pattern(Pattern) { + setDependence(computeDependence(this)); + } PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {} @@ -4123,17 +4112,17 @@ class SizeOfPackExpr final /// the given parameter pack. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, - Optional Length, ArrayRef PartialArgs) - : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/!Length, - /*InstantiationDependent=*/!Length, - /*ContainsUnexpandedParameterPack=*/false), + Optional Length, + ArrayRef PartialArgs) + : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(Length ? *Length : PartialArgs.size()), Pack(Pack) { assert((!Length || PartialArgs.empty()) && "have partial args for non-dependent sizeof... expression"); auto *Args = getTrailingObjects(); std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args); + setDependence(Length ? ExprDependence::None + : ExprDependence::ValueInstantiation); } /// Create an empty expression. @@ -4224,12 +4213,10 @@ public: SourceLocation Loc, NonTypeTemplateParmDecl *Param, Expr *Replacement) - : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary, - Replacement->isTypeDependent(), Replacement->isValueDependent(), - Replacement->isInstantiationDependent(), - Replacement->containsUnexpandedParameterPack()), + : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary), Param(Param), Replacement(Replacement) { SubstNonTypeTemplateParmExprBits.NameLoc = Loc; + setDependence(computeDependence(this)); } SourceLocation getNameLoc() const { @@ -4543,13 +4530,12 @@ public: CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, Optional NumExpansions) - : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary, - /*Dependent*/ true, true, true, - /*ContainsUnexpandedParameterPack*/ false), - LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), + : 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; + setDependence(computeDependence(this)); } CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {} @@ -4624,27 +4610,25 @@ public: Expr *Ready, Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) : Expr(SC, Resume->getType(), Resume->getValueKind(), - Resume->getObjectKind(), Resume->isTypeDependent(), - Resume->isValueDependent(), Common->isInstantiationDependent(), - Common->containsUnexpandedParameterPack()), + Resume->getObjectKind()), KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) { SubExprs[SubExpr::Common] = Common; SubExprs[SubExpr::Ready] = Ready; SubExprs[SubExpr::Suspend] = Suspend; SubExprs[SubExpr::Resume] = Resume; + setDependence(computeDependence(this)); } CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, Expr *Common) - : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true, - Common->containsUnexpandedParameterPack()), - KeywordLoc(KeywordLoc) { + : Expr(SC, Ty, VK_RValue, OK_Ordinary), KeywordLoc(KeywordLoc) { assert(Common->isTypeDependent() && Ty->isDependentType() && "wrong constructor for non-dependent co_await/co_yield expression"); SubExprs[SubExpr::Common] = Common; SubExprs[SubExpr::Ready] = nullptr; SubExprs[SubExpr::Suspend] = nullptr; SubExprs[SubExpr::Resume] = nullptr; + setDependence(computeDependence(this)); } CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { @@ -4741,10 +4725,7 @@ class DependentCoawaitExpr : public Expr { public: DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op, UnresolvedLookupExpr *OpCoawait) - : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary, - /*TypeDependent*/ true, /*ValueDependent*/ true, - /*InstantiationDependent*/ true, - Op->containsUnexpandedParameterPack()), + : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary), KeywordLoc(KeywordLoc) { // NOTE: A co_await expression is dependent on the coroutines promise // type and may be dependent even when the `Op` expression is not. @@ -4752,6 +4733,7 @@ public: "wrong constructor for non-dependent co_await/co_yield expression"); SubExprs[0] = Op; SubExprs[1] = OpCoawait; + setDependence(computeDependence(this)); } DependentCoawaitExpr(EmptyShell Empty) @@ -4826,6 +4808,8 @@ public: : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, DstType), KWLoc(KWLoc), RParenLoc(RParenLoc) {} + BuiltinBitCastExpr(EmptyShell Empty) + : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0) {} SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } diff --git a/gnu/llvm/clang/include/clang/AST/ExprConcepts.h b/gnu/llvm/clang/include/clang/AST/ExprConcepts.h index 271d487e2fc..2a88ed5175d 100644 --- a/gnu/llvm/clang/include/clang/AST/ExprConcepts.h +++ b/gnu/llvm/clang/include/clang/AST/ExprConcepts.h @@ -149,6 +149,7 @@ public: enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested }; private: const RequirementKind Kind; + // FIXME: use RequirementDependence to model dependence? bool Dependent : 1; bool ContainsUnexpandedParameterPack : 1; bool Satisfied : 1; @@ -550,4 +551,4 @@ public: } // namespace clang -#endif // LLVM_CLANG_AST_EXPRCONCEPTS_H \ No newline at end of file +#endif // LLVM_CLANG_AST_EXPRCONCEPTS_H diff --git a/gnu/llvm/clang/include/clang/AST/ExprObjC.h b/gnu/llvm/clang/include/clang/AST/ExprObjC.h index d76b3a26b1f..4b39d9ab96a 100644 --- a/gnu/llvm/clang/include/clang/AST/ExprObjC.h +++ b/gnu/llvm/clang/include/clang/AST/ExprObjC.h @@ -13,8 +13,10 @@ #ifndef LLVM_CLANG_AST_EXPROBJC_H #define LLVM_CLANG_AST_EXPROBJC_H +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/SelectorLocationsKind.h" @@ -53,9 +55,10 @@ class ObjCStringLiteral : public Expr { public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) - : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - String(SL), AtLoc(L) {} + : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary), String(SL), + AtLoc(L) { + setDependence(ExprDependence::None); + } explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} @@ -88,9 +91,10 @@ class ObjCBoolLiteralExpr : public Expr { public: ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) - : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), - Value(val), Loc(l) {} + : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary), Value(val), + Loc(l) { + setDependence(ExprDependence::None); + } explicit ObjCBoolLiteralExpr(EmptyShell Empty) : Expr(ObjCBoolLiteralExprClass, Empty) {} @@ -129,13 +133,11 @@ class ObjCBoxedExpr : public Expr { public: friend class ASTStmtReader; - ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, - SourceRange R) - : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, - E->isTypeDependent(), E->isValueDependent(), - E->isInstantiationDependent(), - E->containsUnexpandedParameterPack()), - SubExpr(E), BoxingMethod(method), Range(R) {} + ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, SourceRange R) + : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary), SubExpr(E), + BoxingMethod(method), Range(R) { + setDependence(computeDependence(this)); + } explicit ObjCBoxedExpr(EmptyShell Empty) : Expr(ObjCBoxedExprClass, Empty) {} @@ -409,14 +411,12 @@ class ObjCEncodeExpr : public Expr { SourceLocation AtLoc, RParenLoc; public: - ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, - SourceLocation at, SourceLocation rp) - : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, - EncodedType->getType()->isDependentType(), - EncodedType->getType()->isDependentType(), - EncodedType->getType()->isInstantiationDependentType(), - EncodedType->getType()->containsUnexpandedParameterPack()), - EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} + ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at, + SourceLocation rp) + : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary), + EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) { + setDependence(computeDependence(this)); + } explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} @@ -456,11 +456,12 @@ class ObjCSelectorExpr : public Expr { SourceLocation AtLoc, RParenLoc; public: - ObjCSelectorExpr(QualType T, Selector selInfo, - SourceLocation at, SourceLocation rp) - : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - SelName(selInfo), AtLoc(at), RParenLoc(rp) {} + ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, + SourceLocation rp) + : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary), + SelName(selInfo), AtLoc(at), RParenLoc(rp) { + setDependence(ExprDependence::None); + } explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} @@ -508,11 +509,12 @@ public: friend class ASTStmtReader; friend class ASTStmtWriter; - ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, - SourceLocation at, SourceLocation protoLoc, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} + ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, + SourceLocation protoLoc, SourceLocation rp) + : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary), + TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) { + setDependence(ExprDependence::None); + } explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} @@ -558,17 +560,15 @@ class ObjCIvarRefExpr : public Expr { bool IsFreeIvar : 1; public: - ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, - SourceLocation l, SourceLocation oploc, - Expr *base, - bool arrow = false, bool freeIvar = false) + ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, + SourceLocation oploc, Expr *base, bool arrow = false, + bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, VK_LValue, - d->isBitField() ? OK_BitField : OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), + d->isBitField() ? OK_BitField : OK_Ordinary), D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow), - IsFreeIvar(freeIvar) {} + IsFreeIvar(freeIvar) { + setDependence(computeDependence(this)); + } explicit ObjCIvarRefExpr(EmptyShell Empty) : Expr(ObjCIvarRefExprClass, Empty) {} @@ -645,57 +645,53 @@ private: llvm::PointerUnion Receiver; public: - ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation l, Expr *base) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) { + ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, Expr *base) + : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false), + IdLoc(l), Receiver(base) { assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } - ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation l, SourceLocation sl, QualType st) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false, st->isInstantiationDependentType(), - st->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl), - Receiver(st.getTypePtr()) { + ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, SourceLocation sl, + QualType st) + : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false), + IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, Expr *Base) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, - Base->isValueDependent(), Base->isInstantiationDependent(), - Base->containsUnexpandedParameterPack()), + : Expr(ObjCPropertyRefExprClass, T, VK, OK), PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), Receiver(Base) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, - SourceLocation IdLoc, - SourceLocation SuperLoc, QualType SuperTy) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), + SourceLocation IdLoc, SourceLocation SuperLoc, + QualType SuperTy) + : Expr(ObjCPropertyRefExprClass, T, VK, OK), PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, - SourceLocation IdLoc, - SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), + SourceLocation IdLoc, SourceLocation ReceiverLoc, + ObjCInterfaceDecl *Receiver) + : Expr(ObjCPropertyRefExprClass, T, VK, OK), PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } explicit ObjCPropertyRefExpr(EmptyShell Empty) @@ -859,20 +855,14 @@ class ObjCSubscriptRefExpr : public Expr { ObjCMethodDecl *SetAtIndexMethodDecl; public: - ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, - ExprValueKind VK, ExprObjectKind OK, - ObjCMethodDecl *getMethod, + ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, ExprValueKind VK, + ExprObjectKind OK, ObjCMethodDecl *getMethod, ObjCMethodDecl *setMethod, SourceLocation RB) - : Expr(ObjCSubscriptRefExprClass, T, VK, OK, - base->isTypeDependent() || key->isTypeDependent(), - base->isValueDependent() || key->isValueDependent(), - (base->isInstantiationDependent() || - key->isInstantiationDependent()), - (base->containsUnexpandedParameterPack() || - key->containsUnexpandedParameterPack())), - RBracket(RB), GetAtIndexMethodDecl(getMethod), - SetAtIndexMethodDecl(setMethod) { - SubExprs[BASE] = base; SubExprs[KEY] = key; + : Expr(ObjCSubscriptRefExprClass, T, VK, OK), RBracket(RB), + GetAtIndexMethodDecl(getMethod), SetAtIndexMethodDecl(setMethod) { + SubExprs[BASE] = base; + SubExprs[KEY] = key; + setDependence(computeDependence(this)); } explicit ObjCSubscriptRefExpr(EmptyShell Empty) @@ -1505,11 +1495,10 @@ class ObjCIsaExpr : public Expr { public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, QualType ty) - : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - /*ContainsUnexpandedParameterPack=*/false), - Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} + : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary), Base(base), + IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) { + setDependence(computeDependence(this)); + } /// Build an empty expression. explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {} @@ -1591,12 +1580,10 @@ class ObjCIndirectCopyRestoreExpr : public Expr { public: ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) - : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, - operand->isTypeDependent(), operand->isValueDependent(), - operand->isInstantiationDependent(), - operand->containsUnexpandedParameterPack()), + : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary), Operand(operand) { setShouldCopy(shouldCopy); + setDependence(computeDependence(this)); } Expr *getSubExpr() { return cast(Operand); } @@ -1705,9 +1692,10 @@ class ObjCAvailabilityCheckExpr : public Expr { public: ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, SourceLocation RParen, QualType Ty) - : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false, - false, false, false), - VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {} + : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary), + VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) { + setDependence(ExprDependence::None); + } explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) : Expr(ObjCAvailabilityCheckExprClass, Shell) {} diff --git a/gnu/llvm/clang/include/clang/AST/ExprOpenMP.h b/gnu/llvm/clang/include/clang/AST/ExprOpenMP.h index 5607d2d1dc5..be5dda99233 100644 --- a/gnu/llvm/clang/include/clang/AST/ExprOpenMP.h +++ b/gnu/llvm/clang/include/clang/AST/ExprOpenMP.h @@ -13,62 +13,66 @@ #ifndef LLVM_CLANG_AST_EXPROPENMP_H #define LLVM_CLANG_AST_EXPROPENMP_H +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Expr.h" namespace clang { -/// OpenMP 4.0 [2.4, Array Sections]. +/// OpenMP 5.0 [2.1.5, Array Sections]. /// To specify an array section in an OpenMP construct, array subscript /// expressions are extended with the following syntax: /// \code +/// [ lower-bound : length : stride ] +/// [ lower-bound : length : ] /// [ lower-bound : length ] +/// [ lower-bound : : stride ] +/// [ lower-bound : : ] /// [ lower-bound : ] +/// [ : length : stride ] +/// [ : length : ] /// [ : length ] +/// [ : : stride ] +/// [ : : ] /// [ : ] /// \endcode /// The array section must be a subset of the original array. /// Array sections are allowed on multidimensional arrays. Base language array /// subscript expressions can be used to specify length-one dimensions of /// multidimensional array sections. -/// The lower-bound and length are integral type expressions. When evaluated +/// Each of the lower-bound, length, and stride expressions if specified must be +/// an integral type expressions of the base language. When evaluated /// they represent a set of integer values as follows: /// \code -/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length - -/// 1 } +/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , +/// lower-bound + ((length - 1) * stride) } /// \endcode /// The lower-bound and length must evaluate to non-negative integers. +/// The stride must evaluate to a positive integer. /// When the size of the array dimension is not known, the length must be /// specified explicitly. -/// When the length is absent, it defaults to the size of the array dimension -/// minus the lower-bound. -/// When the lower-bound is absent it defaults to 0. +/// When the stride is absent it defaults to 1. +/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, +/// where size is the size of the array dimension. When the lower-bound is +/// absent it defaults to 0. class OMPArraySectionExpr : public Expr { - enum { BASE, LOWER_BOUND, LENGTH, END_EXPR }; + enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR }; Stmt *SubExprs[END_EXPR]; - SourceLocation ColonLoc; + SourceLocation ColonLocFirst; + SourceLocation ColonLocSecond; SourceLocation RBracketLoc; public: - OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation ColonLoc, SourceLocation RBracketLoc) - : Expr( - OMPArraySectionExprClass, Type, VK, OK, - Base->isTypeDependent() || - (LowerBound && LowerBound->isTypeDependent()) || - (Length && Length->isTypeDependent()), - Base->isValueDependent() || - (LowerBound && LowerBound->isValueDependent()) || - (Length && Length->isValueDependent()), - Base->isInstantiationDependent() || - (LowerBound && LowerBound->isInstantiationDependent()) || - (Length && Length->isInstantiationDependent()), - Base->containsUnexpandedParameterPack() || - (LowerBound && LowerBound->containsUnexpandedParameterPack()) || - (Length && Length->containsUnexpandedParameterPack())), - ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) { + OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, + QualType Type, ExprValueKind VK, ExprObjectKind OK, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, SourceLocation RBracketLoc) + : Expr(OMPArraySectionExprClass, Type, VK, OK), + ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), + RBracketLoc(RBracketLoc) { SubExprs[BASE] = Base; SubExprs[LOWER_BOUND] = LowerBound; SubExprs[LENGTH] = Length; + SubExprs[STRIDE] = Stride; + setDependence(computeDependence(this)); } /// Create an empty array section expression. @@ -100,13 +104,22 @@ public: /// Set length of the array section. void setLength(Expr *E) { SubExprs[LENGTH] = E; } + /// Get stride of array section. + Expr *getStride() { return cast_or_null(SubExprs[STRIDE]); } + const Expr *getStride() const { return cast_or_null(SubExprs[STRIDE]); } + /// Set length of the array section. + void setStride(Expr *E) { SubExprs[STRIDE] = E; } + SourceLocation getBeginLoc() const LLVM_READONLY { return getBase()->getBeginLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } - SourceLocation getColonLoc() const { return ColonLoc; } - void setColonLoc(SourceLocation L) { ColonLoc = L; } + SourceLocation getColonLocFirst() const { return ColonLocFirst; } + void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } + + SourceLocation getColonLocSecond() const { return ColonLocSecond; } + void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; } SourceLocation getRBracketLoc() const { return RBracketLoc; } void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } @@ -127,6 +140,286 @@ public: return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); } }; + +/// An explicit cast in C or a C-style cast in C++, which uses the syntax +/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f. +class OMPArrayShapingExpr final + : public Expr, + private llvm::TrailingObjects { + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + /// Base node. + SourceLocation LPLoc; /// The location of the left paren + SourceLocation RPLoc; /// The location of the right paren + unsigned NumDims = 0; /// Number of dimensions in the shaping expression. + + /// Construct full expression. + OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L, + SourceLocation R, ArrayRef Dims); + + /// Construct an empty expression. + explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims) + : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {} + + /// Sets the dimensions for the array shaping. + void setDimensions(ArrayRef Dims); + + /// Sets the base expression for array shaping operation. + void setBase(Expr *Op) { getTrailingObjects()[NumDims] = Op; } + + /// Sets source ranges for the brackets in the array shaping operation. + void setBracketsRanges(ArrayRef BR); + + unsigned numTrailingObjects(OverloadToken) const { + // Add an extra one for the base expression. + return NumDims + 1; + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumDims; + } + +public: + static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T, + Expr *Op, SourceLocation L, + SourceLocation R, ArrayRef Dims, + ArrayRef BracketRanges); + + static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context, + unsigned NumDims); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { + return getBase()->getEndLoc(); + } + + /// Fetches the dimensions for array shaping expression. + ArrayRef getDimensions() const { + return llvm::makeArrayRef(getTrailingObjects(), NumDims); + } + + /// Fetches source ranges for the brackets os the array shaping expression. + ArrayRef getBracketsRanges() const { + return llvm::makeArrayRef(getTrailingObjects(), NumDims); + } + + /// Fetches base expression of array shaping expression. + Expr *getBase() { return getTrailingObjects()[NumDims]; } + const Expr *getBase() const { return getTrailingObjects()[NumDims]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPArrayShapingExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast(getTrailingObjects()); + return child_range(Begin, Begin + NumDims + 1); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range(Begin, Begin + NumDims + 1); + } +}; + +/// Helper expressions and declaration for OMPIteratorExpr class for each +/// iteration space. +struct OMPIteratorHelperData { + /// Internal normalized counter. + VarDecl *CounterVD = nullptr; + /// Normalized upper bound. Normalized loop iterates from 0 to Upper with + /// step 1. + Expr *Upper = nullptr; + /// Update expression for the originally specified iteration variable, + /// calculated as VD = Begin + CounterVD * Step; + Expr *Update = nullptr; + /// Updater for the internal counter: ++CounterVD; + Expr *CounterUpdate = nullptr; +}; + +/// OpenMP 5.0 [2.1.6 Iterators] +/// Iterators are identifiers that expand to multiple values in the clause on +/// which they appear. +/// The syntax of the iterator modifier is as follows: +/// \code +/// iterator(iterators-definition) +/// \endcode +/// where iterators-definition is one of the following: +/// \code +/// iterator-specifier [, iterators-definition ] +/// \endcode +/// where iterator-specifier is one of the following: +/// \code +/// [ iterator-type ] identifier = range-specification +/// \endcode +/// where identifier is a base language identifier. +/// iterator-type is a type name. +/// range-specification is of the form begin:end[:step], where begin and end are +/// expressions for which their types can be converted to iterator-type and step +/// is an integral expression. +/// In an iterator-specifier, if the iterator-type is not specified then the +/// type of that iterator is of int type. +/// The iterator-type must be an integral or pointer type. +/// The iterator-type must not be const qualified. +class OMPIteratorExpr final + : public Expr, + private llvm::TrailingObjects { +public: + /// Iterator range representation begin:end[:step]. + struct IteratorRange { + Expr *Begin = nullptr; + Expr *End = nullptr; + Expr *Step = nullptr; + }; + /// Iterator definition representation. + struct IteratorDefinition { + Decl *IteratorDecl = nullptr; + IteratorRange Range; + SourceLocation AssignmentLoc; + SourceLocation ColonLoc, SecondColonLoc; + }; + +private: + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + /// Offset in the list of expressions for subelements of the ranges. + enum class RangeExprOffset { + Begin = 0, + End = 1, + Step = 2, + Total = 3, + }; + /// Offset in the list of locations for subelements of colon symbols + /// locations. + enum class RangeLocOffset { + AssignLoc = 0, + FirstColonLoc = 1, + SecondColonLoc = 2, + Total = 3, + }; + /// Location of 'iterator' keyword. + SourceLocation IteratorKwLoc; + /// Location of '('. + SourceLocation LPLoc; + /// Location of ')'. + SourceLocation RPLoc; + /// Number of iterator definitions. + unsigned NumIterators = 0; + + OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc, + SourceLocation L, SourceLocation R, + ArrayRef Data, + ArrayRef Helpers); + + /// Construct an empty expression. + explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators) + : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {} + + /// Sets basic declaration for the specified iterator definition. + void setIteratorDeclaration(unsigned I, Decl *D); + + /// Sets the location of the assignment symbol for the specified iterator + /// definition. + void setAssignmentLoc(unsigned I, SourceLocation Loc); + + /// Sets begin, end and optional step expressions for specified iterator + /// definition. + void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc, + Expr *End, SourceLocation SecondColonLoc, Expr *Step); + + /// Sets helpers for the specified iteration space. + void setHelper(unsigned I, const OMPIteratorHelperData &D); + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators; + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators * static_cast(RangeExprOffset::Total); + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators * static_cast(RangeLocOffset::Total); + } + +public: + static OMPIteratorExpr *Create(const ASTContext &Context, QualType T, + SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, + ArrayRef Data, + ArrayRef Helpers); + + static OMPIteratorExpr *CreateEmpty(const ASTContext &Context, + unsigned NumIterators); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; } + void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; } + SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; } + + /// Gets the iterator declaration for the given iterator. + Decl *getIteratorDecl(unsigned I); + const Decl *getIteratorDecl(unsigned I) const { + return const_cast(this)->getIteratorDecl(I); + } + + /// Gets the iterator range for the given iterator. + IteratorRange getIteratorRange(unsigned I); + const IteratorRange getIteratorRange(unsigned I) const { + return const_cast(this)->getIteratorRange(I); + } + + /// Gets the location of '=' for the given iterator definition. + SourceLocation getAssignLoc(unsigned I) const; + /// Gets the location of the first ':' in the range for the given iterator + /// definition. + SourceLocation getColonLoc(unsigned I) const; + /// Gets the location of the second ':' (if any) in the range for the given + /// iteratori definition. + SourceLocation getSecondColonLoc(unsigned I) const; + + /// Returns number of iterator definitions. + unsigned numOfIterators() const { return NumIterators; } + + /// Fetches helper data for the specified iteration space. + OMPIteratorHelperData &getHelper(unsigned I); + const OMPIteratorHelperData &getHelper(unsigned I) const; + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPIteratorExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast(getTrailingObjects()); + return child_range( + Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range( + Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); + } +}; + } // end namespace clang #endif diff --git a/gnu/llvm/clang/include/clang/AST/ExternalASTSource.h b/gnu/llvm/clang/include/clang/AST/ExternalASTSource.h index 899ac3f6693..def877b9181 100644 --- a/gnu/llvm/clang/include/clang/AST/ExternalASTSource.h +++ b/gnu/llvm/clang/include/clang/AST/ExternalASTSource.h @@ -17,7 +17,6 @@ #include "clang/AST/CharUnits.h" #include "clang/AST/DeclBase.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -39,6 +38,7 @@ namespace clang { class ASTConsumer; class ASTContext; +class ASTSourceDescriptor; class CXXBaseSpecifier; class CXXCtorInitializer; class CXXRecordDecl; @@ -165,31 +165,6 @@ public: /// object file. virtual bool DeclIsFromPCHWithObjectFile(const Decl *D) { return false; } - /// Abstracts clang modules and precompiled header files and holds - /// everything needed to generate debug info for an imported module - /// or PCH. - class ASTSourceDescriptor { - StringRef PCHModuleName; - StringRef Path; - StringRef ASTFile; - ASTFileSignature Signature; - const Module *ClangModule = nullptr; - - public: - ASTSourceDescriptor() = default; - ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, - ASTFileSignature Signature) - : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(const Module &M); - - std::string getModuleName() const; - StringRef getPath() const { return Path; } - StringRef getASTFile() const { return ASTFile; } - ASTFileSignature getSignature() const { return Signature; } - const Module *getModuleOrNull() const { return ClangModule; } - }; - /// Return a descriptor for the corresponding module, if one exists. virtual llvm::Optional getSourceDescriptor(unsigned ID); @@ -504,9 +479,8 @@ struct PointerLikeTypeTraits< static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } - enum { - NumLowBitsAvailable = PointerLikeTypeTraits::NumLowBitsAvailable - 1 - }; + static constexpr int NumLowBitsAvailable = + PointerLikeTypeTraits::NumLowBitsAvailable - 1; }; } // namespace llvm diff --git a/gnu/llvm/clang/include/clang/AST/FormatString.h b/gnu/llvm/clang/include/clang/AST/FormatString.h index 231ff6a116e..8c944451f79 100644 --- a/gnu/llvm/clang/include/clang/AST/FormatString.h +++ b/gnu/llvm/clang/include/clang/AST/FormatString.h @@ -227,10 +227,8 @@ public: bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) || kind == FreeBSDrArg || kind == FreeBSDyArg; } - bool isUIntArg() const { return (kind >= UIntArgBeg && kind <= UIntArgEnd) || - kind == FreeBSDbArg; } - bool isAnyIntArg() const { return (kind >= IntArgBeg && kind <= UIntArgEnd) || - kind == FreeBSDbArg; } + bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } + bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } diff --git a/gnu/llvm/clang/include/clang/AST/GlobalDecl.h b/gnu/llvm/clang/include/clang/AST/GlobalDecl.h index 145e961a23a..d8ac498be54 100644 --- a/gnu/llvm/clang/include/clang/AST/GlobalDecl.h +++ b/gnu/llvm/clang/include/clang/AST/GlobalDecl.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_GLOBALDECL_H #define LLVM_CLANG_AST_GLOBALDECL_H +#include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" @@ -33,17 +34,31 @@ enum class DynamicInitKind : unsigned { AtExit, }; +enum class KernelReferenceKind : unsigned { + Kernel = 0, + Stub = 1, +}; + /// GlobalDecl - represents a global declaration. This can either be a /// CXXConstructorDecl and the constructor type (Base, Complete). -/// a CXXDestructorDecl and the destructor type (Base, Complete) or +/// a CXXDestructorDecl and the destructor type (Base, Complete), +/// a FunctionDecl and the kernel reference type (Kernel, Stub), or /// a VarDecl, a FunctionDecl or a BlockDecl. +/// +/// When a new type of GlobalDecl is added, the following places should +/// be updated to convert a Decl* to a GlobalDecl: +/// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp. +/// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp +/// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp +/// class GlobalDecl { - llvm::PointerIntPair Value; + llvm::PointerIntPair Value; unsigned MultiVersionIndex = 0; void Init(const Decl *D) { assert(!isa(D) && "Use other ctor with ctor decls!"); assert(!isa(D) && "Use other ctor with dtor decls!"); + assert(!D->hasAttr() && "Use other ctor with GPU kernels!"); Value.setPointer(D); } @@ -53,8 +68,17 @@ public: GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0) : MultiVersionIndex(MVIndex) { - Init(D); + if (!D->hasAttr()) { + Init(D); + return; + } + Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D))); + } + GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind) + : Value(D, unsigned(Kind)) { + assert(D->hasAttr() && "Decl is not a GPU kernel!"); } + GlobalDecl(const NamedDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } @@ -94,13 +118,22 @@ public: } unsigned getMultiVersionIndex() const { - assert(isa(getDecl()) && + assert(isa( + getDecl()) && + !cast(getDecl())->hasAttr() && !isa(getDecl()) && !isa(getDecl()) && "Decl is not a plain FunctionDecl!"); return MultiVersionIndex; } + KernelReferenceKind getKernelReferenceKind() const { + assert(isa(getDecl()) && + cast(getDecl())->hasAttr() && + "Decl is not a GPU kernel!"); + return static_cast(Value.getInt()); + } + friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { return LHS.Value == RHS.Value && LHS.MultiVersionIndex == RHS.MultiVersionIndex; @@ -108,12 +141,19 @@ public: void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + explicit operator bool() const { return getAsOpaquePtr(); } + static GlobalDecl getFromOpaquePtr(void *P) { GlobalDecl GD; GD.Value.setFromOpaqueValue(P); return GD; } + static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) { + return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel + : KernelReferenceKind::Stub; + } + GlobalDecl getWithDecl(const Decl *D) { GlobalDecl Result(*this); Result.Value.setPointer(D); @@ -136,6 +176,7 @@ public: GlobalDecl getWithMultiVersionIndex(unsigned Index) { assert(isa(getDecl()) && + !cast(getDecl())->hasAttr() && !isa(getDecl()) && !isa(getDecl()) && "Decl is not a plain FunctionDecl!"); @@ -143,6 +184,15 @@ public: Result.MultiVersionIndex = Index; return Result; } + + GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) { + assert(isa(getDecl()) && + cast(getDecl())->hasAttr() && + "Decl is not a GPU kernel!"); + GlobalDecl Result(*this); + Result.Value.setInt(unsigned(Kind)); + return Result; + } }; } // namespace clang diff --git a/gnu/llvm/clang/include/clang/AST/JSONNodeDumper.h b/gnu/llvm/clang/include/clang/AST/JSONNodeDumper.h index 4023e023e9d..4e716299241 100644 --- a/gnu/llvm/clang/include/clang/AST/JSONNodeDumper.h +++ b/gnu/llvm/clang/include/clang/AST/JSONNodeDumper.h @@ -23,10 +23,13 @@ #include "clang/AST/CommentVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Mangle.h" +#include "clang/AST/Type.h" #include "llvm/Support/JSON.h" namespace clang { +class APValue; + class NodeStreamer { bool FirstChild = true; bool TopLevel = true; @@ -64,7 +67,7 @@ public: // We need to capture an owning-string in the lambda because the lambda // is invoked in a deferred manner. - std::string LabelStr = !Label.empty() ? Label : "inner"; + std::string LabelStr(!Label.empty() ? Label : "inner"); bool WasFirstChild = FirstChild; auto DumpWithIndent = [=](bool IsLastChild) { if (WasFirstChild) { @@ -201,6 +204,7 @@ public: void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); void VisitTypedefType(const TypedefType *TT); void VisitFunctionType(const FunctionType *T); diff --git a/gnu/llvm/clang/include/clang/AST/LocInfoType.h b/gnu/llvm/clang/include/clang/AST/LocInfoType.h index 1073174bcf9..7e845ad0358 100644 --- a/gnu/llvm/clang/include/clang/AST/LocInfoType.h +++ b/gnu/llvm/clang/include/clang/AST/LocInfoType.h @@ -35,10 +35,7 @@ class LocInfoType : public Type { TypeSourceInfo *DeclInfo; LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isInstantiationDependentType(), ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { + : Type((TypeClass)LocInfo, ty, ty->getDependence()), DeclInfo(TInfo) { assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); } friend class Sema; diff --git a/gnu/llvm/clang/include/clang/AST/Mangle.h b/gnu/llvm/clang/include/clang/AST/Mangle.h index 5db5c5b977d..011d1faab8e 100644 --- a/gnu/llvm/clang/include/clang/AST/Mangle.h +++ b/gnu/llvm/clang/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_MANGLE_H #include "clang/AST/Decl.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -96,8 +97,8 @@ public: virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0; // FIXME: consider replacing raw_ostream & with something like SmallString &. - void mangleName(const NamedDecl *D, raw_ostream &); - virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; + void mangleName(GlobalDecl GD, raw_ostream &); + virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; @@ -109,11 +110,8 @@ public: raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; - virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - raw_ostream &) = 0; - virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - raw_ostream &) = 0; virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0; + virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&); void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, @@ -151,9 +149,14 @@ public: }; 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; @@ -172,12 +175,17 @@ public: virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0; + 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); + DiagnosticsEngine &Diags, + bool IsUniqueNameMangler = false); }; class MicrosoftMangleContext : public MangleContext { diff --git a/gnu/llvm/clang/include/clang/AST/NestedNameSpecifier.h b/gnu/llvm/clang/include/clang/AST/NestedNameSpecifier.h index c6fae6f465f..540ac3df48f 100644 --- a/gnu/llvm/clang/include/clang/AST/NestedNameSpecifier.h +++ b/gnu/llvm/clang/include/clang/AST/NestedNameSpecifier.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H +#include "clang/AST/DependenceFlags.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/FoldingSet.h" @@ -199,6 +200,8 @@ public: return nullptr; } + NestedNameSpecifierDependence getDependence() const; + /// Whether this nested name specifier refers to a dependent /// type or not. bool isDependent() const; @@ -211,6 +214,9 @@ public: /// parameter pack (for C++11 variadic templates). bool containsUnexpandedParameterPack() const; + /// Whether this nested name specifier contains an error. + bool containsErrors() const; + /// Print this nested name specifier to the given output stream. If /// `ResolveTemplateArguments` is true, we'll print actual types, e.g. /// `ns::SomeTemplate` instead of diff --git a/gnu/llvm/clang/include/clang/AST/NonTrivialTypeVisitor.h b/gnu/llvm/clang/include/clang/AST/NonTrivialTypeVisitor.h index aafcedb9d10..c95516538ad 100644 --- a/gnu/llvm/clang/include/clang/AST/NonTrivialTypeVisitor.h +++ b/gnu/llvm/clang/include/clang/AST/NonTrivialTypeVisitor.h @@ -1,4 +1,4 @@ -//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===// +//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial 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. diff --git a/gnu/llvm/clang/include/clang/AST/ODRHash.h b/gnu/llvm/clang/include/clang/AST/ODRHash.h index cd4a6f37f5d..2e8593e0b83 100644 --- a/gnu/llvm/clang/include/clang/AST/ODRHash.h +++ b/gnu/llvm/clang/include/clang/AST/ODRHash.h @@ -89,7 +89,7 @@ public: // Save booleans until the end to lower the size of data to process. void AddBoolean(bool value); - static bool isWhitelistedDecl(const Decl* D, const DeclContext *Parent); + static bool isDeclToBeProcessed(const Decl* D, const DeclContext *Parent); private: void AddDeclarationNameImpl(DeclarationName Name); diff --git a/gnu/llvm/clang/include/clang/AST/OpenMPClause.h b/gnu/llvm/clang/include/clang/AST/OpenMPClause.h index 26f8389f9cf..6de7b6deb51 100644 --- a/gnu/llvm/clang/include/clang/AST/OpenMPClause.h +++ b/gnu/llvm/clang/include/clang/AST/OpenMPClause.h @@ -31,6 +31,7 @@ #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" +#include "llvm/Frontend/OpenMP/OMPContext.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" @@ -284,12 +285,13 @@ public: /// \param EndLoc Ending location of the clause. OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), - Allocator(A) {} + : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc), + LParenLoc(LParenLoc), Allocator(A) {} /// Build an empty clause. OMPAllocatorClause() - : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -314,7 +316,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocator; + return T->getClauseKind() == llvm::omp::OMPC_allocator; } }; @@ -349,17 +351,17 @@ class OMPAllocateClause final OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_allocate, StartLoc, LParenLoc, - EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_allocate, StartLoc, + LParenLoc, EndLoc, N), Allocator(Allocator), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPAllocateClause(unsigned N) - : OMPVarListClause(OMPC_allocate, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_allocate, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -411,7 +413,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocate; + return T->getClauseKind() == llvm::omp::OMPC_allocate; } }; @@ -469,15 +471,16 @@ public: OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) - : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), - NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { + : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), + ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -511,7 +514,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_if; + return T->getClauseKind() == llvm::omp::OMPC_if; } }; @@ -547,14 +550,14 @@ public: OMPFinalClause(Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond) { + : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPFinalClause() - : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -579,7 +582,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_final; + return T->getClauseKind() == llvm::omp::OMPC_final; } }; @@ -617,7 +620,7 @@ public: OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_threads, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumThreads(NumThreads) { setPreInitStmt(HelperNumThreads, CaptureRegion); @@ -625,7 +628,8 @@ public: /// Build an empty clause. OMPNumThreadsClause() - : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -651,7 +655,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_threads; + return T->getClauseKind() == llvm::omp::OMPC_num_threads; } }; @@ -687,12 +691,13 @@ public: /// \param EndLoc Ending location of the clause. OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Safelen(Len) {} + : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Safelen(Len) {} /// Build an empty clause. explicit OMPSafelenClause() - : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -717,7 +722,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_safelen; + return T->getClauseKind() == llvm::omp::OMPC_safelen; } }; @@ -752,12 +757,13 @@ public: /// \param EndLoc Ending location of the clause. OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Simdlen(Len) {} + : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Simdlen(Len) {} /// Build an empty clause. explicit OMPSimdlenClause() - : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -782,7 +788,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simdlen; + return T->getClauseKind() == llvm::omp::OMPC_simdlen; } }; @@ -818,12 +824,13 @@ public: /// \param EndLoc Ending location of the clause. OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num) {} + : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num) {} /// Build an empty clause. explicit OMPCollapseClause() - : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -848,7 +855,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_collapse; + return T->getClauseKind() == llvm::omp::OMPC_collapse; } }; @@ -866,7 +873,7 @@ class OMPDefaultClause : public OMPClause { SourceLocation LParenLoc; /// A kind of the 'default' clause. - OpenMPDefaultClauseKind Kind = OMPC_DEFAULT_unknown; + llvm::omp::DefaultKind Kind = llvm::omp::OMP_DEFAULT_unknown; /// Start location of the kind in source code. SourceLocation KindKwLoc; @@ -874,7 +881,7 @@ class OMPDefaultClause : public OMPClause { /// Set kind of the clauses. /// /// \param K Argument of clause. - void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } + void setDefaultKind(llvm::omp::DefaultKind K) { Kind = K; } /// Set argument location. /// @@ -889,15 +896,16 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, + OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -906,7 +914,7 @@ public: SourceLocation getLParenLoc() const { return LParenLoc; } /// Returns kind of the clause. - OpenMPDefaultClauseKind getDefaultKind() const { return Kind; } + llvm::omp::DefaultKind getDefaultKind() const { return Kind; } /// Returns location of clause kind. SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } @@ -927,7 +935,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; + return T->getClauseKind() == llvm::omp::OMPC_default; } }; @@ -973,12 +981,13 @@ public: OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPProcBindClause() - : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1008,7 +1017,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_proc_bind; + return T->getClauseKind() == llvm::omp::OMPC_proc_bind; } }; @@ -1028,11 +1037,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedAddressClause() - : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1050,7 +1060,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_address; + return T->getClauseKind() == llvm::omp::OMPC_unified_address; } }; @@ -1070,11 +1080,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedSharedMemoryClause() - : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1092,7 +1103,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_shared_memory; + return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory; } }; @@ -1112,11 +1123,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} /// Build an empty clause. OMPReverseOffloadClause() - : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1134,7 +1146,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reverse_offload; + return T->getClauseKind() == llvm::omp::OMPC_reverse_offload; } }; @@ -1154,12 +1166,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} /// Build an empty clause. OMPDynamicAllocatorsClause() - : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) { - } + : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1177,7 +1189,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dynamic_allocators; + return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators; } }; @@ -1229,12 +1241,12 @@ public: SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPAtomicDefaultMemOrderClause() - : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. @@ -1267,7 +1279,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_atomic_default_mem_order; + return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order; } }; @@ -1386,9 +1398,9 @@ public: Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), - ChunkSize(ChunkSize) { + : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; @@ -1398,7 +1410,7 @@ public: /// Build an empty clause. explicit OMPScheduleClause() - : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; @@ -1460,7 +1472,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_schedule; + return T->getClauseKind() == llvm::omp::OMPC_schedule; } }; @@ -1495,12 +1507,12 @@ class OMPOrderedClause final /// \param EndLoc Ending location of the clause. OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num), NumberOfLoops(NumLoops) {} + : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} /// Build an empty clause. explicit OMPOrderedClause(unsigned NumLoops) - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), NumberOfLoops(NumLoops) {} /// Set the number of associated for-loops. @@ -1556,7 +1568,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_ordered; + return T->getClauseKind() == llvm::omp::OMPC_ordered; } }; @@ -1573,11 +1585,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nowait, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {} /// Build an empty clause. OMPNowaitClause() - : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1595,7 +1607,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nowait; + return T->getClauseKind() == llvm::omp::OMPC_nowait; } }; @@ -1612,11 +1624,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_untied, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} /// Build an empty clause. OMPUntiedClause() - : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1634,7 +1646,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_untied; + return T->getClauseKind() == llvm::omp::OMPC_untied; } }; @@ -1652,11 +1664,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} /// Build an empty clause. OMPMergeableClause() - : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1674,7 +1687,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_mergeable; + return T->getClauseKind() == llvm::omp::OMPC_mergeable; } }; @@ -1691,10 +1704,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_read, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} /// Build an empty clause. - OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {} + OMPReadClause() + : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1712,7 +1726,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_read; + return T->getClauseKind() == llvm::omp::OMPC_read; } }; @@ -1729,11 +1743,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_write, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} /// Build an empty clause. OMPWriteClause() - : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1751,7 +1765,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_write; + return T->getClauseKind() == llvm::omp::OMPC_write; } }; @@ -1762,18 +1776,95 @@ public: /// #pragma omp atomic update /// \endcode /// In this example directive '#pragma omp atomic' has 'update' clause. -class OMPUpdateClause : public OMPClause { -public: +/// Also, this class represents 'update' clause in '#pragma omp depobj' +/// directive. +/// +/// \code +/// #pragma omp depobj(a) update(in) +/// \endcode +/// In this example directive '#pragma omp depobj' has 'update' clause with 'in' +/// dependence kind. +class OMPUpdateClause final + : public OMPClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend TrailingObjects; + + /// true if extended version of the clause for 'depobj' directive. + bool IsExtended = 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) const { + // 2 locations: for '(' and argument location. + return IsExtended ? 2 : 0; + } + + /// Sets the the location of '(' in clause for 'depobj' directive. + void setLParenLoc(SourceLocation Loc) { + assert(IsExtended && "Expected extended clause."); + *getTrailingObjects() = Loc; + } + + /// Sets the the location of '(' in clause for 'depobj' directive. + void setArgumentLoc(SourceLocation Loc) { + assert(IsExtended && "Expected extended clause."); + *std::next(getTrailingObjects(), 1) = Loc; + } + + /// Sets the dependence kind for the clause for 'depobj' directive. + void setDependencyKind(OpenMPDependClauseKind DK) { + assert(IsExtended && "Expected extended clause."); + *getTrailingObjects() = DK; + } + /// Build 'update' clause. /// /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_update, StartLoc, EndLoc) {} + OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, + bool IsExtended) + : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), + IsExtended(IsExtended) {} /// Build an empty clause. - OMPUpdateClause() - : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {} + OMPUpdateClause(bool IsExtended) + : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), + IsExtended(IsExtended) {} + +public: + /// Creates clause for 'atomic' directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc); + + /// Creates clause for 'depobj' directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ArgumentLoc Location of the argument. + /// \param DK Dependence kind. + /// \param EndLoc Ending location of the clause. + static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation ArgumentLoc, + OpenMPDependClauseKind DK, + SourceLocation EndLoc); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param IsExtended true if extended clause for 'depobj' directive must be + /// created. + static OMPUpdateClause *CreateEmpty(const ASTContext &C, bool IsExtended); + + /// Checks if the clause is the extended clauses for 'depobj' directive. + bool isExtended() const { return IsExtended; } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1790,8 +1881,26 @@ public: return const_child_range(const_child_iterator(), const_child_iterator()); } + /// Gets the the location of '(' in clause for 'depobj' directive. + SourceLocation getLParenLoc() const { + assert(IsExtended && "Expected extended clause."); + return *getTrailingObjects(); + } + + /// Gets the the location of argument in clause for 'depobj' directive. + SourceLocation getArgumentLoc() const { + assert(IsExtended && "Expected extended clause."); + return *std::next(getTrailingObjects(), 1); + } + + /// Gets the dependence kind in clause for 'depobj' directive. + OpenMPDependClauseKind getDependencyKind() const { + assert(IsExtended && "Expected extended clause."); + return *getTrailingObjects(); + } + static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_update; + return T->getClauseKind() == llvm::omp::OMPC_update; } }; @@ -1809,11 +1918,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_capture, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} /// Build an empty clause. OMPCaptureClause() - : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1831,7 +1941,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_capture; + return T->getClauseKind() == llvm::omp::OMPC_capture; } }; @@ -1849,11 +1959,176 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} /// Build an empty clause. OMPSeqCstClause() - : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_seq_cst; + } +}; + +/// This represents 'acq_rel' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush acq_rel +/// \endcode +/// In this example directive '#pragma omp flush' has 'acq_rel' clause. +class OMPAcqRelClause final : public OMPClause { +public: + /// Build 'ack_rel' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPAcqRelClause() + : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_acq_rel; + } +}; + +/// This represents 'acquire' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush acquire +/// \endcode +/// In this example directive '#pragma omp flush' has 'acquire' clause. +class OMPAcquireClause final : public OMPClause { +public: + /// Build 'acquire' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPAcquireClause() + : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_acquire; + } +}; + +/// This represents 'release' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush release +/// \endcode +/// In this example directive '#pragma omp flush' has 'release' clause. +class OMPReleaseClause final : public OMPClause { +public: + /// Build 'release' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPReleaseClause() + : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_release; + } +}; + +/// This represents 'relaxed' clause in the '#pragma omp atomic' +/// directives. +/// +/// \code +/// #pragma omp atomic relaxed +/// \endcode +/// In this example directive '#pragma omp atomic' has 'relaxed' clause. +class OMPRelaxedClause final : public OMPClause { +public: + /// Build 'relaxed' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPRelaxedClause() + : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1871,7 +2146,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_seq_cst; + return T->getClauseKind() == llvm::omp::OMPC_relaxed; } }; @@ -1897,16 +2172,16 @@ class OMPPrivateClause final /// \param N Number of the variables in the clause. OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_private, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_private, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPPrivateClause(unsigned N) - : OMPVarListClause(OMPC_private, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_private, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets the list of references to private copies with initializers for /// new private variables. @@ -1976,7 +2251,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_private; + return T->getClauseKind() == llvm::omp::OMPC_private; } }; @@ -2004,8 +2279,8 @@ class OMPFirstprivateClause final /// \param N Number of the variables in the clause. OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_firstprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPreInit(this) {} /// Build an empty clause. @@ -2013,7 +2288,7 @@ class OMPFirstprivateClause final /// \param N Number of variables. explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause( - OMPC_firstprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPreInit(this) {} @@ -2117,7 +2392,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_firstprivate; + return T->getClauseKind() == llvm::omp::OMPC_firstprivate; } }; @@ -2170,8 +2445,8 @@ class OMPLastprivateClause final SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, unsigned N) - : OMPVarListClause(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_lastprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), ColonLoc(ColonLoc) {} @@ -2180,7 +2455,7 @@ class OMPLastprivateClause final /// \param N Number of variables. explicit OMPLastprivateClause(unsigned N) : OMPVarListClause( - OMPC_lastprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2356,7 +2631,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_lastprivate; + return T->getClauseKind() == llvm::omp::OMPC_lastprivate; } }; @@ -2381,16 +2656,16 @@ class OMPSharedClause final /// \param N Number of the variables in the clause. OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_shared, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_shared, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPSharedClause(unsigned N) - : OMPVarListClause(OMPC_shared, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_shared, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -2428,7 +2703,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_shared; + return T->getClauseKind() == llvm::omp::OMPC_shared; } }; @@ -2448,6 +2723,12 @@ class OMPReductionClause final friend OMPVarListClause; friend TrailingObjects; + /// Reduction modifier. + OpenMPReductionClauseModifier Modifier = OMPC_REDUCTION_unknown; + + /// Reduction modifier location. + SourceLocation ModifierLoc; + /// Location of ':'. SourceLocation ColonLoc; @@ -2461,29 +2742,39 @@ class OMPReductionClause final /// /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. - /// \param EndLoc Ending location of the clause. + /// \param ModifierLoc Modifier location. /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. /// \param N Number of the variables in the clause. /// \param QualifierLoc The nested-name qualifier with location information /// \param NameInfo The full name info for reduction identifier. OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, + SourceLocation ModifierLoc, SourceLocation ColonLoc, + SourceLocation EndLoc, + OpenMPReductionClauseModifier Modifier, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_reduction, StartLoc, - LParenLoc, EndLoc, N), - OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), + : OMPVarListClause(llvm::omp::OMPC_reduction, + StartLoc, LParenLoc, EndLoc, N), + OMPClauseWithPostUpdate(this), Modifier(Modifier), + ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPReductionClause(unsigned N) - : OMPVarListClause(OMPC_reduction, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_reduction, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), OMPClauseWithPostUpdate(this) {} + /// Sets reduction modifier. + void setModifier(OpenMPReductionClauseModifier M) { Modifier = M; } + + /// Sets location of the modifier. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -2548,11 +2839,47 @@ class OMPReductionClause final return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); } + /// Set list of helper copy operations for inscan reductions. + /// The form is: Temps[i] = LHS[i]; + void setInscanCopyOps(ArrayRef Ops); + + /// Get the list of helper inscan copy operations. + MutableArrayRef getInscanCopyOps() { + return MutableArrayRef(getReductionOps().end(), varlist_size()); + } + ArrayRef getInscanCopyOps() const { + return llvm::makeArrayRef(getReductionOps().end(), varlist_size()); + } + + /// Set list of helper temp vars for inscan copy array operations. + void setInscanCopyArrayTemps(ArrayRef CopyArrayTemps); + + /// Get the list of helper inscan copy temps. + MutableArrayRef getInscanCopyArrayTemps() { + return MutableArrayRef(getInscanCopyOps().end(), varlist_size()); + } + ArrayRef getInscanCopyArrayTemps() const { + return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size()); + } + + /// Set list of helper temp elements vars for inscan copy array operations. + void setInscanCopyArrayElems(ArrayRef CopyArrayElems); + + /// Get the list of helper inscan copy temps. + MutableArrayRef getInscanCopyArrayElems() { + return MutableArrayRef(getInscanCopyArrayTemps().end(), + varlist_size()); + } + ArrayRef getInscanCopyArrayElems() const { + return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size()); + } + public: /// Creates clause with a list of variables \a VL. /// /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. + /// \param ModifierLoc Modifier location. /// \param ColonLoc Location of ':'. /// \param EndLoc Ending location of the clause. /// \param VL The variables in the clause. @@ -2577,23 +2904,41 @@ public: /// \endcode /// Required for proper codegen of final reduction operation performed by the /// reduction clause. + /// \param CopyOps List of copy operations for inscan reductions: + /// \code + /// TempExprs = LHSExprs; + /// \endcode + /// \param CopyArrayTemps Temp arrays for prefix sums. + /// \param CopyArrayElems Temp arrays for prefix sums. /// \param PreInit Statement that must be executed before entering the OpenMP /// region with this clause. /// \param PostUpdate Expression that must be executed after exit from the /// OpenMP region with this clause. static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef VL, - NestedNameSpecifierLoc QualifierLoc, + SourceLocation ModifierLoc, SourceLocation ColonLoc, + SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, + ArrayRef VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef Privates, ArrayRef LHSExprs, ArrayRef RHSExprs, - ArrayRef ReductionOps, Stmt *PreInit, Expr *PostUpdate); + ArrayRef ReductionOps, ArrayRef CopyOps, + ArrayRef CopyArrayTemps, ArrayRef CopyArrayElems, + Stmt *PreInit, Expr *PostUpdate); /// Creates an empty clause with the place for \a N variables. /// /// \param C AST context. /// \param N The number of variables. - static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N); + /// \param Modifier Reduction modifier. + static OMPReductionClause * + CreateEmpty(const ASTContext &C, unsigned N, + OpenMPReductionClauseModifier Modifier); + + /// Returns modifier. + OpenMPReductionClauseModifier getModifier() const { return Modifier; } + + /// Returns modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } /// Gets location of ':' symbol in clause. SourceLocation getColonLoc() const { return ColonLoc; } @@ -2644,6 +2989,36 @@ public: getReductionOps().end()); } + helper_expr_const_range copy_ops() const { + return helper_expr_const_range(getInscanCopyOps().begin(), + getInscanCopyOps().end()); + } + + helper_expr_range copy_ops() { + return helper_expr_range(getInscanCopyOps().begin(), + getInscanCopyOps().end()); + } + + helper_expr_const_range copy_array_temps() const { + return helper_expr_const_range(getInscanCopyArrayTemps().begin(), + getInscanCopyArrayTemps().end()); + } + + helper_expr_range copy_array_temps() { + return helper_expr_range(getInscanCopyArrayTemps().begin(), + getInscanCopyArrayTemps().end()); + } + + helper_expr_const_range copy_array_elems() const { + return helper_expr_const_range(getInscanCopyArrayElems().begin(), + getInscanCopyArrayElems().end()); + } + + helper_expr_range copy_array_elems() { + return helper_expr_range(getInscanCopyArrayElems().begin(), + getInscanCopyArrayElems().end()); + } + child_range children() { return child_range(reinterpret_cast(varlist_begin()), reinterpret_cast(varlist_end())); @@ -2664,7 +3039,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reduction; + return T->getClauseKind() == llvm::omp::OMPC_reduction; } }; @@ -2706,8 +3081,8 @@ class OMPTaskReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_task_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause( + llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2716,7 +3091,7 @@ class OMPTaskReductionClause final /// \param N Number of variables. explicit OMPTaskReductionClause(unsigned N) : OMPVarListClause( - OMPC_task_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2896,7 +3271,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_task_reduction; + return T->getClauseKind() == llvm::omp::OMPC_task_reduction; } }; @@ -2937,8 +3312,8 @@ class OMPInReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_in_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_in_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2947,7 +3322,7 @@ class OMPInReductionClause final /// \param N Number of variables. explicit OMPInReductionClause(unsigned N) : OMPVarListClause( - OMPC_in_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3151,7 +3526,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_in_reduction; + return T->getClauseKind() == llvm::omp::OMPC_in_reduction; } }; @@ -3197,8 +3572,8 @@ class OMPLinearClause final OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_linear, StartLoc, + LParenLoc, EndLoc, NumVars), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} @@ -3206,9 +3581,9 @@ class OMPLinearClause final /// /// \param NumVars Number of variables. explicit OMPLinearClause(unsigned NumVars) - : OMPVarListClause(OMPC_linear, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_linear, SourceLocation(), SourceLocation(), - NumVars), + SourceLocation(), NumVars), OMPClauseWithPostUpdate(this) {} /// Gets the list of initial values for linear variables. @@ -3428,7 +3803,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_linear; + return T->getClauseKind() == llvm::omp::OMPC_linear; } }; @@ -3463,17 +3838,17 @@ class OMPAlignedClause final OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_aligned, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_aligned, StartLoc, + LParenLoc, EndLoc, NumVars), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param NumVars Number of variables. explicit OMPAlignedClause(unsigned NumVars) - : OMPVarListClause(OMPC_aligned, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_aligned, SourceLocation(), SourceLocation(), - NumVars) {} + SourceLocation(), NumVars) {} public: /// Creates clause with a list of variables \a VL and alignment \a A. @@ -3527,7 +3902,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_aligned; + return T->getClauseKind() == llvm::omp::OMPC_aligned; } }; @@ -3566,16 +3941,16 @@ class OMPCopyinClause final /// \param N Number of the variables in the clause. OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyin, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyin, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyinClause(unsigned N) - : OMPVarListClause(OMPC_copyin, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_copyin, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent source expression in the final @@ -3703,7 +4078,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyin; + return T->getClauseKind() == llvm::omp::OMPC_copyin; } }; @@ -3730,15 +4105,16 @@ class OMPCopyprivateClause final /// \param N Number of the variables in the clause. OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyprivate, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyprivate, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyprivateClause(unsigned N) : OMPVarListClause( - OMPC_copyprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the @@ -3866,7 +4242,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyprivate; + return T->getClauseKind() == llvm::omp::OMPC_copyprivate; } }; @@ -3896,16 +4272,16 @@ class OMPFlushClause final /// \param N Number of the variables in the clause. OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_flush, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_flush, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPFlushClause(unsigned N) - : OMPVarListClause(OMPC_flush, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_flush, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -3943,32 +4319,119 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_flush; + return T->getClauseKind() == llvm::omp::OMPC_flush; } }; -/// This represents implicit clause 'depend' for the '#pragma omp task' +/// This represents implicit clause 'depobj' for the '#pragma omp depobj' /// directive. +/// This clause does not exist by itself, it can be only as a part of 'omp +/// depobj' directive. This clause is introduced to keep the original structure +/// of \a OMPExecutableDirective class and its derivatives and to use the +/// existing infrastructure of clauses with the list of variables. /// /// \code -/// #pragma omp task depend(in:a,b) +/// #pragma omp depobj(a) destroy /// \endcode -/// In this example directive '#pragma omp task' with clause 'depend' with the -/// variables 'a' and 'b' with dependency 'in'. -class OMPDependClause final - : public OMPVarListClause, - private llvm::TrailingObjects { +/// In this example directive '#pragma omp depobj' has implicit clause 'depobj' +/// with the depobj 'a'. +class OMPDepobjClause final : public OMPClause { friend class OMPClauseReader; - friend OMPVarListClause; - friend TrailingObjects; - /// Dependency type (one of in, out, inout). - OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; + /// Location of '('. + SourceLocation LParenLoc; - /// Dependency type location. - SourceLocation DepLoc; + /// Chunk size. + Expr *Depobj = nullptr; - /// Colon location. + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), + LParenLoc(LParenLoc) {} + + /// Build an empty clause. + /// + explicit OMPDepobjClause() + : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} + + void setDepobj(Expr *E) { Depobj = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + +public: + /// Creates clause. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param Depobj depobj expression associated with the 'depobj' directive. + static OMPDepobjClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, Expr *Depobj); + + /// Creates an empty clause. + /// + /// \param C AST context. + static OMPDepobjClause *CreateEmpty(const ASTContext &C); + + /// Returns depobj expression associated with the clause. + Expr *getDepobj() { return Depobj; } + const Expr *getDepobj() const { return Depobj; } + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + child_range children() { + return child_range(reinterpret_cast(&Depobj), + reinterpret_cast(&Depobj) + 1); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_depobj; + } +}; + +/// This represents implicit clause 'depend' for the '#pragma omp task' +/// directive. +/// +/// \code +/// #pragma omp task depend(in:a,b) +/// \endcode +/// In this example directive '#pragma omp task' with clause 'depend' with the +/// variables 'a' and 'b' with dependency 'in'. +class OMPDependClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Dependency type (one of in, out, inout). + OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; + + /// Dependency type location. + SourceLocation DepLoc; + + /// Colon location. SourceLocation ColonLoc; /// Number of loops, associated with the depend clause. @@ -3984,8 +4447,9 @@ class OMPDependClause final /// clause. OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, StartLoc, LParenLoc, - EndLoc, N), NumLoops(NumLoops) {} + : OMPVarListClause(llvm::omp::OMPC_depend, StartLoc, + LParenLoc, EndLoc, N), + NumLoops(NumLoops) {} /// Build an empty clause. /// @@ -3993,9 +4457,9 @@ class OMPDependClause final /// \param NumLoops Number of loops that is associated with this depend /// clause. explicit OMPDependClause(unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_depend, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), NumLoops(NumLoops) {} /// Set dependency kind. @@ -4007,6 +4471,9 @@ class OMPDependClause final /// Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + /// Sets optional dependency modifier. + void setModifier(Expr *DepModifier); + public: /// Creates clause with a list of variables \a VL. /// @@ -4022,7 +4489,7 @@ public: /// clause. static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, + SourceLocation EndLoc, Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VL, unsigned NumLoops); @@ -4039,6 +4506,12 @@ public: /// Get dependency type. OpenMPDependClauseKind getDependencyKind() const { return DepKind; } + /// Return optional depend modifier. + Expr *getModifier(); + const Expr *getModifier() const { + return const_cast(this)->getModifier(); + } + /// Get dependency type location. SourceLocation getDependencyLoc() const { return DepLoc; } @@ -4074,7 +4547,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depend; + return T->getClauseKind() == llvm::omp::OMPC_depend; } }; @@ -4092,6 +4565,12 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { /// Location of '('. SourceLocation LParenLoc; + /// Device clause modifier. + OpenMPDeviceClauseModifier Modifier = OMPC_DEVICE_unknown; + + /// Location of the modifier. + SourceLocation ModifierLoc; + /// Device number. Stmt *Device = nullptr; @@ -4100,26 +4579,36 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { /// \param E Device number. void setDevice(Expr *E) { Device = E; } + /// Sets modifier. + void setModifier(OpenMPDeviceClauseModifier M) { Modifier = M; } + + /// Setst modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + public: /// Build 'device' clause. /// + /// \param Modifier Clause modifier. /// \param E Expression associated with this clause. /// \param CaptureRegion Innermost OpenMP region where expressions in this /// clause must be captured. /// \param StartLoc Starting location of the clause. + /// \param ModifierLoc Modifier location. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPDeviceClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, - SourceLocation StartLoc, SourceLocation LParenLoc, + OMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *E, Stmt *HelperE, + OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc) - : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Device(E) { + : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), Device(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPDeviceClause() - : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -4134,6 +4623,12 @@ public: /// Return device number. Expr *getDevice() const { return cast(Device); } + /// Gets modifier. + OpenMPDeviceClauseModifier getModifier() const { return Modifier; } + + /// Gets modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + child_range children() { return child_range(&Device, &Device + 1); } const_child_range children() const { @@ -4148,7 +4643,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_device; + return T->getClauseKind() == llvm::omp::OMPC_device; } }; @@ -4165,11 +4660,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_threads, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {} /// Build an empty clause. OMPThreadsClause() - : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4187,7 +4683,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_threads; + return T->getClauseKind() == llvm::omp::OMPC_threads; } }; @@ -4204,10 +4700,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} /// Build an empty clause. - OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + OMPSIMDClause() + : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4225,7 +4722,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simd; + return T->getClauseKind() == llvm::omp::OMPC_simd; } }; @@ -4853,19 +5350,14 @@ class OMPMapClause final : public OMPMappableExprListClause, return getUniqueDeclarationsNum() + getTotalComponentListNum(); } -public: - /// Number of allowed map-type-modifiers. - static constexpr unsigned NumberOfModifiers = - OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1; - private: /// Map-type-modifiers for the 'map' clause. - OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = { + OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = { OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; /// Location of map-type-modifiers for the 'map' clause. - SourceLocation MapTypeModifiersLoc[NumberOfModifiers]; + SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers]; /// Map type for the 'map' clause. OpenMPMapClauseKind MapType = OMPC_MAP_unknown; @@ -4906,8 +5398,8 @@ private: OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo), + : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && "Unexpected number of map type modifiers."); @@ -4927,14 +5419,15 @@ private: /// 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(OMPC_map, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), + Sizes) {} /// Set map-type-modifier for the clause. /// /// \param I index for map-type-modifier. /// \param T map-type-modifier for the clause. void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) { - assert(I < NumberOfModifiers && + assert(I < NumberOfOMPMapClauseModifiers && "Unexpected index to store map type modifier, exceeds array size."); MapTypeModifiers[I] = T; } @@ -4944,7 +5437,7 @@ private: /// \param I index for map-type-modifier location. /// \param TLoc map-type-modifier location. void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) { - assert(I < NumberOfModifiers && + assert(I < NumberOfOMPMapClauseModifiers && "Index to store map type modifier location exceeds array size."); MapTypeModifiersLoc[I] = TLoc; } @@ -5019,7 +5512,7 @@ public: /// /// \param Cnt index for map-type-modifier. OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY { - assert(Cnt < NumberOfModifiers && + assert(Cnt < NumberOfOMPMapClauseModifiers && "Requested modifier exceeds the total number of modifiers."); return MapTypeModifiers[Cnt]; } @@ -5029,7 +5522,7 @@ public: /// /// \param Cnt index for map-type-modifier location. SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { - assert(Cnt < NumberOfModifiers && + assert(Cnt < NumberOfOMPMapClauseModifiers && "Requested modifier location exceeds total number of modifiers."); return MapTypeModifiersLoc[Cnt]; } @@ -5074,7 +5567,7 @@ public: static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_map; + return T->getClauseKind() == llvm::omp::OMPC_map; } }; @@ -5113,14 +5606,15 @@ public: OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTeams(E) { + : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPNumTeamsClause() - : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5149,7 +5643,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_teams; + return T->getClauseKind() == llvm::omp::OMPC_num_teams; } }; @@ -5189,14 +5683,15 @@ public: OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPThreadLimitClause() - : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5225,7 +5720,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_thread_limit; + return T->getClauseKind() == llvm::omp::OMPC_thread_limit; } }; @@ -5264,14 +5759,14 @@ public: OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Priority(Priority) { + : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { setPreInitStmt(HelperPriority, CaptureRegion); } /// Build an empty clause. OMPPriorityClause() - : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5299,7 +5794,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_priority; + return T->getClauseKind() == llvm::omp::OMPC_priority; } }; @@ -5335,14 +5830,15 @@ public: OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Grainsize(Size) { + : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPGrainsizeClause() - : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5367,7 +5863,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_grainsize; + return T->getClauseKind() == llvm::omp::OMPC_grainsize; } }; @@ -5384,11 +5880,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} /// Build an empty clause. OMPNogroupClause() - : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -5406,7 +5903,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nogroup; + return T->getClauseKind() == llvm::omp::OMPC_nogroup; } }; @@ -5442,14 +5939,15 @@ public: OMPNumTasksClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTasks(Size) { + : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPNumTasksClause() - : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5474,7 +5972,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_tasks; + return T->getClauseKind() == llvm::omp::OMPC_num_tasks; } }; @@ -5506,11 +6004,12 @@ public: /// \param EndLoc Ending location of the clause. OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), Hint(Hint) {} /// Build an empty clause. - OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {} + OMPHintClause() + : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -5535,7 +6034,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_hint; + return T->getClauseKind() == llvm::omp::OMPC_hint; } }; @@ -5607,7 +6106,7 @@ public: SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, Stmt *HelperChunkSize) - : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); @@ -5615,7 +6114,8 @@ public: /// Build an empty clause. explicit OMPDistScheduleClause() - : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Get kind of the clause. @@ -5654,7 +6154,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dist_schedule; + return T->getClauseKind() == llvm::omp::OMPC_dist_schedule; } }; @@ -5724,12 +6224,14 @@ public: SourceLocation MLoc, SourceLocation KLoc, SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, OpenMPDefaultmapClauseModifier M) - : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), - Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} + : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), + LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), + KindLoc(KLoc) {} /// Build an empty clause. explicit OMPDefaultmapClause() - : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), + SourceLocation()) {} /// Get kind of the clause. OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } @@ -5766,7 +6268,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_defaultmap; + return T->getClauseKind() == llvm::omp::OMPC_defaultmap; } }; @@ -5804,8 +6306,8 @@ class OMPToClause final : public OMPMappableExprListClause, DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -5815,7 +6317,8 @@ class OMPToClause final : public OMPMappableExprListClause, /// 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(OMPC_to, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -5883,7 +6386,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_to; + return T->getClauseKind() == llvm::omp::OMPC_to; } }; @@ -5922,8 +6425,8 @@ class OMPFromClause final DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -5933,7 +6436,8 @@ class OMPFromClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6001,7 +6505,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_from; + return T->getClauseKind() == llvm::omp::OMPC_from; } }; @@ -6035,7 +6539,8 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { + } /// Build an empty clause. /// @@ -6045,8 +6550,8 @@ class OMPUseDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6164,7 +6669,111 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_use_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr; + } +}; + +/// This represents clause 'use_device_addr' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target data use_device_addr(a,b) +/// \endcode +/// In this example directive '#pragma omp target data' has clause +/// 'use_device_addr' with the variables 'a' and 'b'. +class OMPUseDeviceAddrClause final + : public OMPMappableExprListClause, + private llvm::TrailingObjects< + OMPUseDeviceAddrClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { + friend class OMPClauseReader; + friend OMPMappableExprListClause; + friend OMPVarListClause; + friend TrailingObjects; + + /// Build clause with number of variables \a NumVars. + /// + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// 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 OMPUseDeviceAddrClause(const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, Locs, + Sizes) {} + + /// Build an empty clause. + /// + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// 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 OMPUseDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, + OMPVarListLocTy(), Sizes) {} + + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken) const { + return varlist_size(); + } + size_t numTrailingObjects(OverloadToken) const { + return getUniqueDeclarationsNum(); + } + size_t numTrailingObjects(OverloadToken) const { + return getUniqueDeclarationsNum() + getTotalComponentListNum(); + } + +public: + /// Creates clause with a list of variables \a Vars. + /// + /// \param C AST context. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. + static OMPUseDeviceAddrClause * + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef Vars, ArrayRef Declarations, + MappableExprComponentListsRef ComponentLists); + + /// Creates an empty clause with the place for \a NumVars variables. + /// + /// \param C AST context. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// 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. + static OMPUseDeviceAddrClause * + CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_use_device_addr; } }; @@ -6198,7 +6807,7 @@ class OMPIsDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6208,8 +6817,8 @@ class OMPIsDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6267,7 +6876,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_is_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr; } }; @@ -6293,15 +6902,16 @@ class OMPNontemporalClause final /// \param N Number of the variables in the clause. OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_nontemporal, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_nontemporal, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPNontemporalClause(unsigned N) : OMPVarListClause( - OMPC_nontemporal, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Get the list of privatied copies if the member expression was captured by @@ -6363,62 +6973,682 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nontemporal; + return T->getClauseKind() == llvm::omp::OMPC_nontemporal; } }; -/// This class implements a simple visitor for OMPClause -/// subclasses. -template class Ptr, typename RetTy> -class OMPClauseVisitorBase { +/// This represents 'order' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp simd order(concurrent) +/// \endcode +/// In this example directive '#pragma omp parallel' has simple 'order' +/// clause with kind 'concurrent'. +class OMPOrderClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// A kind of the 'default' clause. + OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown; + + /// Start location of the kind in source code. + SourceLocation KindKwLoc; + + /// Set kind of the clause. + /// + /// \param K Argument of clause. + void setKind(OpenMPOrderClauseKind K) { Kind = K; } + + /// Set argument location. + /// + /// \param KLoc Argument location. + void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } + public: -#define PTR(CLASS) typename Ptr::type -#define DISPATCH(CLASS) \ - return static_cast(this)->Visit##CLASS(static_cast(S)) + /// Build 'order' clause with argument \p A ('concurrent'). + /// + /// \param A Argument of the clause ('concurrent'). + /// \param ALoc Starting location of the argument. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} -#define OPENMP_CLAUSE(Name, Class) \ - RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } -#include "clang/Basic/OpenMPKinds.def" + /// Build an empty clause. + OMPOrderClause() + : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} - RetTy Visit(PTR(OMPClause) S) { - // Top switch clause: visit each OMPClause. - switch (S->getClauseKind()) { - default: llvm_unreachable("Unknown clause kind!"); -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : return Visit ## Class(static_cast(S)); -#include "clang/Basic/OpenMPKinds.def" - } - } - // Base case, ignore it. :) - RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } -#undef PTR -#undef DISPATCH -}; + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } -template -using const_ptr = typename std::add_pointer::type>; + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } -template -class OMPClauseVisitor : - public OMPClauseVisitorBase {}; -template -class ConstOMPClauseVisitor : - public OMPClauseVisitorBase {}; + /// Returns kind of the clause. + OpenMPOrderClauseKind getKind() const { return Kind; } -class OMPClausePrinter final : public OMPClauseVisitor { - raw_ostream &OS; - const PrintingPolicy &Policy; + /// Returns location of clause kind. + SourceLocation getKindKwLoc() const { return KindKwLoc; } - /// Process clauses with list of variables. - template void VisitOMPClauseList(T *Node, char StartSym); + child_range children() { + return child_range(child_iterator(), child_iterator()); + } -public: - OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) - : OS(OS), Policy(Policy) {} + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_order; + } +}; + +/// This represents 'destroy' clause in the '#pragma omp depobj' +/// directive. +/// +/// \code +/// #pragma omp depobj(a) destroy +/// \endcode +/// In this example directive '#pragma omp depobj' has 'destroy' clause. +class OMPDestroyClause final : public OMPClause { +public: + /// Build 'destroy' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPDestroyClause() + : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_destroy; + } +}; + +/// This represents 'detach' clause in the '#pragma omp task' directive. +/// +/// \code +/// #pragma omp task detach(evt) +/// \endcode +/// In this example directive '#pragma omp detach' has simple 'detach' clause +/// with the variable 'evt'. +class OMPDetachClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Expression of the 'detach' clause. + Stmt *Evt = nullptr; + + /// Set condition. + void setEventHandler(Expr *E) { Evt = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + +public: + /// Build 'detach' clause with event-handler \a Evt. + /// + /// \param Evt Event handler expression. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc), + LParenLoc(LParenLoc), Evt(Evt) {} + + /// Build an empty clause. + OMPDetachClause() + : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns event-handler expression. + Expr *getEventHandler() const { return cast_or_null(Evt); } + + child_range children() { return child_range(&Evt, &Evt + 1); } + + const_child_range children() const { + return const_child_range(&Evt, &Evt + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_detach; + } +}; + +/// This represents clause 'inclusive' in the '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan inclusive(a,b) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'inclusive' +/// with the variables 'a' and 'b'. +class OMPInclusiveClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause(llvm::omp::OMPC_inclusive, + StartLoc, LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPInclusiveClause(unsigned N) + : OMPVarListClause(llvm::omp::OMPC_inclusive, + SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the original variables. + static OMPInclusiveClause *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef VL); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPInclusiveClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_inclusive; + } +}; + +/// This represents clause 'exclusive' in the '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan exclusive(a,b) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'exclusive' +/// with the variables 'a' and 'b'. +class OMPExclusiveClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause(llvm::omp::OMPC_exclusive, + StartLoc, LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPExclusiveClause(unsigned N) + : OMPVarListClause(llvm::omp::OMPC_exclusive, + SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the original variables. + static OMPExclusiveClause *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef VL); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPExclusiveClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_exclusive; + } +}; + +/// This represents clause 'uses_allocators' in the '#pragma omp target'-based +/// directives. +/// +/// \code +/// #pragma omp target uses_allocators(default_allocator, my_allocator(traits)) +/// \endcode +/// In this example directive '#pragma omp target' has clause 'uses_allocators' +/// with the allocators 'default_allocator' and user-defined 'my_allocator'. +class OMPUsesAllocatorsClause final + : public OMPClause, + private llvm::TrailingObjects { +public: + /// Data for list of allocators. + struct Data { + /// Allocator. + Expr *Allocator = nullptr; + /// Allocator traits. + Expr *AllocatorTraits = nullptr; + /// Locations of '(' and ')' symbols. + SourceLocation LParenLoc, RParenLoc; + }; + +private: + friend class OMPClauseReader; + friend TrailingObjects; + + enum class ExprOffsets { + Allocator, + AllocatorTraits, + Total, + }; + + enum class ParenLocsOffsets { + LParen, + RParen, + Total, + }; + + /// Location of '('. + SourceLocation LParenLoc; + /// Total number of allocators in the clause. + unsigned NumOfAllocators = 0; + + /// Build clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of allocators asssociated with the clause. + OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumOfAllocators(N) {} + + /// Build an empty clause. + /// \param N Number of allocators asssociated with the clause. + /// + explicit OMPUsesAllocatorsClause(unsigned N) + : OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(), + SourceLocation()), + NumOfAllocators(N) {} + + unsigned numTrailingObjects(OverloadToken) const { + return NumOfAllocators * static_cast(ExprOffsets::Total); + } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Sets the allocators data for the clause. + void setAllocatorsData(ArrayRef Data); + +public: + /// Creates clause with a list of allocators \p Data. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param Data List of allocators. + static OMPUsesAllocatorsClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef Data); + + /// Creates an empty clause with the place for \p N allocators. + /// + /// \param C AST context. + /// \param N The number of allocators. + static OMPUsesAllocatorsClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns number of allocators associated with the clause. + unsigned getNumberOfAllocators() const { return NumOfAllocators; } + + /// Returns data for the specified allocator. + OMPUsesAllocatorsClause::Data getAllocatorData(unsigned I) const; + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast(getTrailingObjects()); + return child_range(Begin, Begin + NumOfAllocators * + static_cast(ExprOffsets::Total)); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range( + Begin, Begin + NumOfAllocators * static_cast(ExprOffsets::Total)); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_uses_allocators; + } +}; + +/// This represents clause 'affinity' in the '#pragma omp task'-based +/// directives. +/// +/// \code +/// #pragma omp task affinity(iterator(i = 0:n) : ([3][n])a, b[:n], c[i]) +/// \endcode +/// In this example directive '#pragma omp task' has clause 'affinity' with the +/// affinity modifer 'iterator(i = 0:n)' and locator items '([3][n])a', 'b[:n]' +/// and 'c[i]'. +class OMPAffinityClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Location of ':' symbol. + SourceLocation ColonLoc; + + /// Build clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. + /// \param N Number of locators asssociated with the clause. + OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) + : OMPVarListClause(llvm::omp::OMPC_affinity, StartLoc, + LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// \param N Number of locators asssociated with the clause. + /// + explicit OMPAffinityClause(unsigned N) + : OMPVarListClause(llvm::omp::OMPC_affinity, + SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + + /// Sets the affinity modifier for the clause, if any. + void setModifier(Expr *E) { + getTrailingObjects()[varlist_size()] = E; + } + + /// Sets the location of ':' symbol. + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + +public: + /// Creates clause with a modifier a list of locator items. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. + /// \param Locators List of locator items. + static OMPAffinityClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation ColonLoc, + SourceLocation EndLoc, Expr *Modifier, + ArrayRef Locators); + + /// Creates an empty clause with the place for \p N locator items. + /// + /// \param C AST context. + /// \param N The number of locator items. + static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// Gets affinity modifier. + Expr *getModifier() { return getTrailingObjects()[varlist_size()]; } + Expr *getModifier() const { + return getTrailingObjects()[varlist_size()]; + } + + /// Gets the location of ':' symbol. + SourceLocation getColonLoc() const { return ColonLoc; } + + // Iterators + child_range children() { + int Offset = getModifier() ? 1 : 0; + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end() + Offset)); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_affinity; + } +}; + +/// This class implements a simple visitor for OMPClause +/// subclasses. +template class Ptr, typename RetTy> +class OMPClauseVisitorBase { +public: +#define PTR(CLASS) Ptr +#define DISPATCH(CLASS) \ + return static_cast(this)->Visit##CLASS(static_cast(S)) + +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } +#include "llvm/Frontend/OpenMP/OMPKinds.def" + + RetTy Visit(PTR(OMPClause) S) { + // Top switch clause: visit each OMPClause. + switch (S->getClauseKind()) { +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return Visit##Class(static_cast(S)); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + default: + break; + } + } + // Base case, ignore it. :) + RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } +#undef PTR +#undef DISPATCH +}; + +template using const_ptr = std::add_pointer_t>; + +template +class OMPClauseVisitor + : public OMPClauseVisitorBase {}; +template +class ConstOMPClauseVisitor : + public OMPClauseVisitorBase {}; + +class OMPClausePrinter final : public OMPClauseVisitor { + raw_ostream &OS; + const PrintingPolicy &Policy; + + /// Process clauses with list of variables. + template void VisitOMPClauseList(T *Node, char StartSym); + +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" +}; + +struct OMPTraitProperty { + llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid; +}; +struct OMPTraitSelector { + Expr *ScoreOrCondition = nullptr; + llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; + llvm::SmallVector Properties; +}; +struct OMPTraitSet { + llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; + llvm::SmallVector Selectors; +}; + +/// Helper data structure representing the traits in a match clause of an +/// `declare variant` or `metadirective`. The outer level is an ordered +/// collection of selector sets, each with an associated kind and an ordered +/// collection of selectors. A selector has a kind, an optional score/condition, +/// and an ordered collection of properties. +class OMPTraitInfo { + /// Private constructor accesible only by ASTContext. + OMPTraitInfo() {} + friend class ASTContext; + +public: + /// Reconstruct a (partial) OMPTraitInfo object from a mangled name. + OMPTraitInfo(StringRef MangledName); + + /// The outermost level of selector sets. + llvm::SmallVector Sets; + + bool anyScoreOrCondition( + llvm::function_ref Cond) { + return llvm::any_of(Sets, [&](OMPTraitSet &Set) { + return llvm::any_of( + Set.Selectors, [&](OMPTraitSelector &Selector) { + return Cond(Selector.ScoreOrCondition, + /* IsScore */ Selector.Kind != + llvm::omp::TraitSelector::user_condition); + }); + }); + } + + /// Create a variant match info object from this trait info object. While the + /// former is a flat representation the actual main difference is that the + /// latter uses clang::Expr to store the score/condition while the former is + /// independent of clang. Thus, expressions and conditions are evaluated in + /// this method. + void getAsVariantMatchInfo(ASTContext &ASTCtx, + llvm::omp::VariantMatchInfo &VMI) const; + + /// Return a string representation identifying this context selector. + std::string getMangledName() const; + + /// 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); } // namespace clang diff --git a/gnu/llvm/clang/include/clang/AST/ParentMapContext.h b/gnu/llvm/clang/include/clang/AST/ParentMapContext.h new file mode 100644 index 00000000000..be4d75df7b9 --- /dev/null +++ b/gnu/llvm/clang/include/clang/AST/ParentMapContext.h @@ -0,0 +1,144 @@ +//===- ParentMapContext.h - Map of parents using DynTypedNode -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Similar to ParentMap.h, but generalizes to non-Stmt nodes, which can have +// multiple parents. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_PARENTMAPCONTEXT_H +#define LLVM_CLANG_AST_PARENTMAPCONTEXT_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTTypeTraits.h" + +namespace clang { +class DynTypedNodeList; + +class ParentMapContext { +public: + ParentMapContext(ASTContext &Ctx); + + ~ParentMapContext(); + + /// Returns the parents of the given node (within the traversal scope). + /// + /// Note that this will lazily compute the parents of all nodes + /// and store them for later retrieval. Thus, the first call is O(n) + /// in the number of AST nodes. + /// + /// Caveats and FIXMEs: + /// Calculating the parent map over all AST nodes will need to load the + /// full AST. This can be undesirable in the case where the full AST is + /// expensive to create (for example, when using precompiled header + /// preambles). Thus, there are good opportunities for optimization here. + /// One idea is to walk the given node downwards, looking for references + /// to declaration contexts - once a declaration context is found, compute + /// the parent map for the declaration context; if that can satisfy the + /// request, loading the whole AST can be avoided. Note that this is made + /// more complex by statements in templates having multiple parents - those + /// problems can be solved by building closure over the templated parts of + /// the AST, which also avoids touching large parts of the AST. + /// Additionally, we will want to add an interface to already give a hint + /// where to search for the parents, for example when looking at a statement + /// inside a certain function. + /// + /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, + /// NestedNameSpecifier or NestedNameSpecifierLoc. + template DynTypedNodeList getParents(const NodeT &Node); + + DynTypedNodeList getParents(const DynTypedNode &Node); + + /// Clear parent maps. + void clear(); + + TraversalKind getTraversalKind() const { return Traversal; } + void setTraversalKind(TraversalKind TK) { Traversal = TK; } + + const Expr *traverseIgnored(const Expr *E) const; + Expr *traverseIgnored(Expr *E) const; + DynTypedNode traverseIgnored(const DynTypedNode &N) const; + +private: + ASTContext &ASTCtx; + class ParentMap; + TraversalKind Traversal = TK_AsIs; + std::unique_ptr Parents; +}; + +class TraversalKindScope { + ParentMapContext &Ctx; + TraversalKind TK = TK_AsIs; + +public: + TraversalKindScope(ASTContext &ASTCtx, llvm::Optional ScopeTK) + : Ctx(ASTCtx.getParentMapContext()) { + TK = Ctx.getTraversalKind(); + if (ScopeTK) + Ctx.setTraversalKind(*ScopeTK); + } + + ~TraversalKindScope() { Ctx.setTraversalKind(TK); } +}; + +/// Container for either a single DynTypedNode or for an ArrayRef to +/// DynTypedNode. For use with ParentMap. +class DynTypedNodeList { + llvm::AlignedCharArrayUnion> Storage; + bool IsSingleNode; + +public: + DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) { + new (Storage.buffer) DynTypedNode(N); + } + + DynTypedNodeList(ArrayRef A) : IsSingleNode(false) { + new (Storage.buffer) ArrayRef(A); + } + + const DynTypedNode *begin() const { + if (!IsSingleNode) + return reinterpret_cast *>(Storage.buffer) + ->begin(); + return reinterpret_cast(Storage.buffer); + } + + const DynTypedNode *end() const { + if (!IsSingleNode) + return reinterpret_cast *>(Storage.buffer) + ->end(); + return reinterpret_cast(Storage.buffer) + 1; + } + + size_t size() const { return end() - begin(); } + bool empty() const { return begin() == end(); } + + const DynTypedNode &operator[](size_t N) const { + assert(N < size() && "Out of bounds!"); + return *(begin() + N); + } +}; + +template +inline DynTypedNodeList ParentMapContext::getParents(const NodeT &Node) { + return getParents(DynTypedNode::create(Node)); +} + +template +inline DynTypedNodeList ASTContext::getParents(const NodeT &Node) { + return getParentMapContext().getParents(Node); +} + +template <> +inline DynTypedNodeList ASTContext::getParents(const DynTypedNode &Node) { + return getParentMapContext().getParents(Node); +} + +} // namespace clang + +#endif diff --git a/gnu/llvm/clang/include/clang/AST/PrettyPrinter.h b/gnu/llvm/clang/include/clang/AST/PrettyPrinter.h index 80eec6a5a8b..616647f4443 100644 --- a/gnu/llvm/clang/include/clang/AST/PrettyPrinter.h +++ b/gnu/llvm/clang/include/clang/AST/PrettyPrinter.h @@ -36,7 +36,9 @@ protected: public: /// Remap a path to a form suitable for printing. - virtual std::string remapPath(StringRef Path) const { return Path; } + virtual std::string remapPath(StringRef Path) const { + return std::string(Path); + } }; /// Describes how types, statements, expressions, and declarations should be @@ -55,12 +57,13 @@ struct PrintingPolicy { SuppressLifetimeQualifiers(false), SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool), Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11), - UseVoidForZeroParams(!LO.CPlusPlus), TerseOutput(false), + UseVoidForZeroParams(!LO.CPlusPlus), + SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false), FullyQualifiedName(false), - PrintCanonicalTypes(false) {} + PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -181,6 +184,10 @@ struct PrintingPolicy { /// with zero parameters. unsigned UseVoidForZeroParams : 1; + /// Whether nested templates must be closed like 'a\ \>' rather than + /// 'a\\>'. + unsigned SplitTemplateClosers : 1; + /// Provide a 'terse' output. /// /// For example, in this mode we don't print function bodies, class members, @@ -237,6 +244,11 @@ struct PrintingPolicy { /// Whether to print types as written or canonically. unsigned PrintCanonicalTypes : 1; + /// Whether to print an InjectedClassNameType with template arguments or as + /// written. When a template argument is unnamed, printing it results in + /// invalid C++ code. + unsigned PrintInjectedClassNameWithArguments : 1; + /// Callbacks to use to allow the behavior of printing to be customized. const PrintingCallbacks *Callbacks = nullptr; }; diff --git a/gnu/llvm/clang/include/clang/AST/RawCommentList.h b/gnu/llvm/clang/include/clang/AST/RawCommentList.h index 1eea56dee62..a18432c2b76 100644 --- a/gnu/llvm/clang/include/clang/AST/RawCommentList.h +++ b/gnu/llvm/clang/include/clang/AST/RawCommentList.h @@ -11,9 +11,9 @@ #include "clang/Basic/CommentOptions.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" #include namespace clang { @@ -21,7 +21,9 @@ namespace clang { class ASTContext; class ASTReader; class Decl; +class DiagnosticsEngine; class Preprocessor; +class SourceManager; namespace comments { class FullComment; @@ -173,23 +175,6 @@ private: friend class ASTReader; }; -/// Compare comments' source locations. -template<> -class BeforeThanCompare { - const SourceManager &SM; - -public: - explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } - - bool operator()(const RawComment &LHS, const RawComment &RHS) { - return SM.isBeforeInTranslationUnit(LHS.getBeginLoc(), RHS.getBeginLoc()); - } - - bool operator()(const RawComment *LHS, const RawComment *RHS) { - return operator()(*LHS, *RHS); - } -}; - /// This class represents all comments included in the translation unit, /// sorted in order of appearance in the translation unit. class RawCommentList { diff --git a/gnu/llvm/clang/include/clang/AST/RecursiveASTVisitor.h b/gnu/llvm/clang/include/clang/AST/RecursiveASTVisitor.h index 86521d82c6f..3dcfc9fee62 100644 --- a/gnu/llvm/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/gnu/llvm/clang/include/clang/AST/RecursiveASTVisitor.h @@ -48,29 +48,6 @@ #include #include -// The following three macros are used for meta programming. The code -// using them is responsible for defining macro OPERATOR(). - -// All unary operators. -#define UNARYOP_LIST() \ - OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \ - OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \ - OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \ - OPERATOR(Extension) OPERATOR(Coawait) - -// All binary operators (excluding compound assign operators). -#define BINOP_LIST() \ - OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \ - OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \ - OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \ - OPERATOR(NE) OPERATOR(Cmp) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \ - OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma) - -// All compound assign operators. -#define CAO_LIST() \ - OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \ - OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor) - namespace clang { // A helper macro to implement short-circuiting when recursing. It @@ -83,6 +60,42 @@ namespace clang { return false; \ } while (false) +namespace detail { + +template +struct has_same_member_pointer_type : std::false_type {}; +template +struct has_same_member_pointer_type + : std::true_type {}; + +template struct is_same_method_impl { + template + static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, + SecondMethodPtrTy SecondMethodPtr) { + return false; + } +}; + +template <> struct is_same_method_impl { + template + static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, + SecondMethodPtrTy SecondMethodPtr) { + return FirstMethodPtr == SecondMethodPtr; + } +}; + +/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr +/// are pointers to the same non-static member function. +template +bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, + SecondMethodPtrTy SecondMethodPtr) { + return is_same_method_impl::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr); +} + +} // end namespace detail + /// A class that does preorder or postorder /// depth-first traversal on the entire Clang AST and visits each node. /// @@ -325,26 +338,20 @@ public: Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); } private: - template - struct has_same_member_pointer_type : std::false_type {}; - template - struct has_same_member_pointer_type - : std::true_type {}; - // Traverse the given statement. If the most-derived traverse function takes a // data recursion queue, pass it on; otherwise, discard it. Note that the // first branch of this conditional must compile whether or not the derived // class can take a queue, so if we're taking the second arm, make the first // arm call our function rather than the derived class version. #define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \ - (has_same_member_pointer_type::value \ - ? static_cast::value \ + ? static_cast::value, \ - Derived &, RecursiveASTVisitor &>::type>(*this) \ + Derived &, RecursiveASTVisitor &>>(*this) \ .Traverse##NAME(static_cast(VAR), QUEUE) \ : getDerived().Traverse##NAME(static_cast(VAR))) @@ -377,60 +384,6 @@ public: bool Visit##CLASS(CLASS *S) { return true; } #include "clang/AST/StmtNodes.inc" -// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary -// operator methods. Unary operators are not classes in themselves -// (they're all opcodes in UnaryOperator) but do have visitors. -#define OPERATOR(NAME) \ - bool TraverseUnary##NAME(UnaryOperator *S, \ - DataRecursionQueue *Queue = nullptr) { \ - if (!getDerived().shouldTraversePostOrder()) \ - TRY_TO(WalkUpFromUnary##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \ - return true; \ - } \ - bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ - TRY_TO(WalkUpFromUnaryOperator(S)); \ - TRY_TO(VisitUnary##NAME(S)); \ - return true; \ - } \ - bool VisitUnary##NAME(UnaryOperator *S) { return true; } - - UNARYOP_LIST() -#undef OPERATOR - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary -// operator methods. Binary operators are not classes in themselves -// (they're all opcodes in BinaryOperator) but do have visitors. -#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \ - bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \ - if (!getDerived().shouldTraversePostOrder()) \ - TRY_TO(WalkUpFromBin##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \ - return true; \ - } \ - bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ - TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \ - TRY_TO(VisitBin##NAME(S)); \ - return true; \ - } \ - bool VisitBin##NAME(BINOP_TYPE *S) { return true; } - -#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator) - BINOP_LIST() -#undef OPERATOR - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound -// assignment methods. Compound assignment operators are not -// classes in themselves (they're all opcodes in -// CompoundAssignOperator) but do have visitors. -#define OPERATOR(NAME) \ - GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator) - - CAO_LIST() -#undef OPERATOR -#undef GENERAL_BINOP_FALLBACK - // ---- Methods on Types ---- // FIXME: revamp to take TypeLoc's rather than Types. @@ -534,8 +487,8 @@ private: bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); bool TraverseOMPLoopDirective(OMPLoopDirective *S); bool TraverseOMPClause(OMPClause *C); -#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Process clauses with list of variables. template bool VisitOMPClauseList(T *Node); /// Process clauses with pre-initis. @@ -549,42 +502,6 @@ private: template bool RecursiveASTVisitor::dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) { -#define DISPATCH_STMT(NAME, CLASS, VAR) \ - return TRAVERSE_STMT_BASE(NAME, CLASS, VAR, Queue); - - // If we have a binary expr, dispatch to the subcode of the binop. A smart - // optimizer (e.g. LLVM) will fold this comparison into the switch stmt - // below. - if (BinaryOperator *BinOp = dyn_cast(S)) { - switch (BinOp->getOpcode()) { -#define OPERATOR(NAME) \ - case BO_##NAME: \ - DISPATCH_STMT(Bin##NAME, BinaryOperator, S); - - BINOP_LIST() -#undef OPERATOR -#undef BINOP_LIST - -#define OPERATOR(NAME) \ - case BO_##NAME##Assign: \ - DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S); - - CAO_LIST() -#undef OPERATOR -#undef CAO_LIST - } - } else if (UnaryOperator *UnOp = dyn_cast(S)) { - switch (UnOp->getOpcode()) { -#define OPERATOR(NAME) \ - case UO_##NAME: \ - DISPATCH_STMT(Unary##NAME, UnaryOperator, S); - - UNARYOP_LIST() -#undef OPERATOR -#undef UNARYOP_LIST - } - } - // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. switch (S->getStmtClass()) { case Stmt::NoStmtClass: @@ -592,7 +509,7 @@ bool RecursiveASTVisitor::dataTraverseNode(Stmt *S, #define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - DISPATCH_STMT(CLASS, CLASS, S); + return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue); #include "clang/AST/StmtNodes.inc" } @@ -603,23 +520,44 @@ bool RecursiveASTVisitor::dataTraverseNode(Stmt *S, template bool RecursiveASTVisitor::PostVisitStmt(Stmt *S) { + // In pre-order traversal mode, each Traverse##STMT method is responsible for + // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and + // does not call the default implementation, the WalkUpFrom callback is not + // called. Post-order traversal mode should provide the same behavior + // regarding method overrides. + // + // In post-order traversal mode the Traverse##STMT method, when it receives a + // DataRecursionQueue, can't call WalkUpFrom after traversing children because + // it only enqueues the children and does not traverse them. TraverseStmt + // traverses the enqueued children, and we call WalkUpFrom here. + // + // However, to make pre-order and post-order modes identical with regards to + // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the + // user did not override the Traverse##STMT method. We implement the override + // check with isSameMethod calls below. + switch (S->getStmtClass()) { case Stmt::NoStmtClass: break; #define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - TRY_TO(WalkUpFrom##CLASS(static_cast(S))); break; + if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \ + &Derived::Traverse##CLASS)) { \ + TRY_TO(WalkUpFrom##CLASS(static_cast(S))); \ + } \ + break; #define INITLISTEXPR(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - { \ + if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \ + &Derived::Traverse##CLASS)) { \ auto ILE = static_cast(S); \ if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \ TRY_TO(WalkUpFrom##CLASS(Syn)); \ if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \ TRY_TO(WalkUpFrom##CLASS(Sem)); \ - break; \ - } + } \ + break; #include "clang/AST/StmtNodes.inc" } @@ -669,9 +607,6 @@ bool RecursiveASTVisitor::TraverseStmt(Stmt *S, return true; } -#define DISPATCH(NAME, CLASS, VAR) \ - return getDerived().Traverse##NAME(static_cast(VAR)) - template bool RecursiveASTVisitor::TraverseType(QualType T) { if (T.isNull()) @@ -681,7 +616,8 @@ bool RecursiveASTVisitor::TraverseType(QualType T) { #define ABSTRACT_TYPE(CLASS, BASE) #define TYPE(CLASS, BASE) \ case Type::CLASS: \ - DISPATCH(CLASS##Type, CLASS##Type, const_cast(T.getTypePtr())); + return getDerived().Traverse##CLASS##Type( \ + static_cast(const_cast(T.getTypePtr()))); #include "clang/AST/TypeNodes.inc" } @@ -731,8 +667,6 @@ bool RecursiveASTVisitor::TraverseDecl(Decl *D) { return true; } -#undef DISPATCH - template bool RecursiveASTVisitor::TraverseNestedNameSpecifier( NestedNameSpecifier *NNS) { @@ -1006,6 +940,17 @@ DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); }) DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); }) +DEF_TRAVERSE_TYPE(ConstantMatrixType, + { TRY_TO(TraverseType(T->getElementType())); }) + +DEF_TRAVERSE_TYPE(DependentSizedMatrixType, { + if (T->getRowExpr()) + TRY_TO(TraverseStmt(T->getRowExpr())); + if (T->getColumnExpr()) + TRY_TO(TraverseStmt(T->getColumnExpr())); + TRY_TO(TraverseType(T->getElementType())); +}) + DEF_TRAVERSE_TYPE(FunctionNoProtoType, { TRY_TO(TraverseType(T->getReturnType())); }) @@ -1115,6 +1060,10 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); }) DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); }) +DEF_TRAVERSE_TYPE(ExtIntType, {}) +DEF_TRAVERSE_TYPE(DependentExtIntType, + { TRY_TO(TraverseStmt(T->getNumBitsExpr())); }) + #undef DEF_TRAVERSE_TYPE // ----------------- TypeLoc traversal ----------------- @@ -1127,10 +1076,17 @@ DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); }) #define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \ template \ bool RecursiveASTVisitor::Traverse##TYPE##Loc(TYPE##Loc TL) { \ - if (getDerived().shouldWalkTypesOfTypeLocs()) \ - TRY_TO(WalkUpFrom##TYPE(const_cast(TL.getTypePtr()))); \ - TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ + if (!getDerived().shouldTraversePostOrder()) { \ + TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ + if (getDerived().shouldWalkTypesOfTypeLocs()) \ + TRY_TO(WalkUpFrom##TYPE(const_cast(TL.getTypePtr()))); \ + } \ { CODE; } \ + if (getDerived().shouldTraversePostOrder()) { \ + TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ + if (getDerived().shouldWalkTypesOfTypeLocs()) \ + TRY_TO(WalkUpFrom##TYPE(const_cast(TL.getTypePtr()))); \ + } \ return true; \ } @@ -1199,22 +1155,22 @@ bool RecursiveASTVisitor::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { DEF_TRAVERSE_TYPELOC(ConstantArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(VariableArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, { @@ -1247,6 +1203,18 @@ DEF_TRAVERSE_TYPELOC(ExtVectorType, { TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); }) +DEF_TRAVERSE_TYPELOC(ConstantMatrixType, { + TRY_TO(TraverseStmt(TL.getAttrRowOperand())); + TRY_TO(TraverseStmt(TL.getAttrColumnOperand())); + TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); +}) + +DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, { + TRY_TO(TraverseStmt(TL.getAttrRowOperand())); + TRY_TO(TraverseStmt(TL.getAttrColumnOperand())); + TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); +}) + DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); }) @@ -1378,6 +1346,11 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) +DEF_TRAVERSE_TYPELOC(ExtIntType, {}) +DEF_TRAVERSE_TYPELOC(DependentExtIntType, { + TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr())); +}) + #undef DEF_TRAVERSE_TYPELOC // ----------------- Decl traversal ----------------- @@ -1986,6 +1959,8 @@ DEF_TRAVERSE_DECL(BindingDecl, { DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); }) +DEF_TRAVERSE_DECL(MSGuidDecl, {}) + DEF_TRAVERSE_DECL(FieldDecl, { TRY_TO(TraverseDeclaratorHelper(D)); if (D->isBitField()) @@ -2062,11 +2037,11 @@ bool RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) { } } - bool VisitBody = D->isThisDeclarationADefinition(); - // If a method is set to default outside the class definition the compiler - // generates the method body and adds it to the AST. - if (const auto *MD = dyn_cast(D)) - VisitBody &= !MD->isDefaulted() || getDerived().shouldVisitImplicitCode(); + bool VisitBody = + D->isThisDeclarationADefinition() && + // Don't visit the function body if the function definition is generated + // by clang. + (!D->isDefaulted() || getDerived().shouldVisitImplicitCode()); if (VisitBody) { TRY_TO(TraverseStmt(D->getBody())); // Function body. @@ -2179,8 +2154,13 @@ DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {}) TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ } \ } \ - if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) \ + /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \ + * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \ + * children, PostVisitStmt will call WalkUpFrom after we are done visiting \ + * children. */ \ + if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \ TRY_TO(WalkUpFrom##STMT(S)); \ + } \ return ReturnValue; \ } @@ -2314,6 +2294,10 @@ DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); +}) + DEF_TRAVERSE_STMT(CXXConstCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) @@ -2347,6 +2331,9 @@ bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr( for (Stmt *SubStmt : S->children()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); } + + if (!Queue && getDerived().shouldTraversePostOrder()) + TRY_TO(WalkUpFromInitListExpr(S)); } return true; } @@ -2543,7 +2530,10 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) // over the children. DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) +DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {}) DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) +DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) +DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); @@ -2661,6 +2651,7 @@ DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, { }) DEF_TRAVERSE_STMT(OpaqueValueExpr, {}) DEF_TRAVERSE_STMT(TypoExpr, {}) +DEF_TRAVERSE_STMT(RecoveryExpr, {}) DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {}) // These operators (all of them) do not need any action except @@ -2842,6 +2833,12 @@ DEF_TRAVERSE_STMT(OMPCancelDirective, DEF_TRAVERSE_STMT(OMPFlushDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPDepobjDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPScanDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPOrderedDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) @@ -2941,16 +2938,15 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { if (!C) return true; switch (C->getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ TRY_TO(Visit##Class(static_cast(C))); \ break; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + default: break; } return true; @@ -3121,6 +3117,26 @@ bool RecursiveASTVisitor::VisitOMPSeqCstClause(OMPSeqCstClause *) { return true; } +template +bool RecursiveASTVisitor::VisitOMPAcqRelClause(OMPAcqRelClause *) { + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPAcquireClause(OMPAcquireClause *) { + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPReleaseClause(OMPReleaseClause *) { + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPRelaxedClause(OMPRelaxedClause *) { + return true; +} + template bool RecursiveASTVisitor::VisitOMPThreadsClause(OMPThreadsClause *) { return true; @@ -3136,6 +3152,11 @@ bool RecursiveASTVisitor::VisitOMPNogroupClause(OMPNogroupClause *) { return true; } +template +bool RecursiveASTVisitor::VisitOMPDestroyClause(OMPDestroyClause *) { + return true; +} + template template bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { @@ -3145,6 +3166,20 @@ bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { return true; } +template +bool RecursiveASTVisitor::VisitOMPInclusiveClause( + OMPInclusiveClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPExclusiveClause( + OMPExclusiveClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + template bool RecursiveASTVisitor::VisitOMPPrivateClause(OMPPrivateClause *C) { TRY_TO(VisitOMPClauseList(C)); @@ -3272,6 +3307,17 @@ RecursiveASTVisitor::VisitOMPReductionClause(OMPReductionClause *C) { for (auto *E : C->reduction_ops()) { TRY_TO(TraverseStmt(E)); } + if (C->getModifier() == OMPC_REDUCTION_inscan) { + for (auto *E : C->copy_ops()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->copy_array_temps()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->copy_array_elems()) { + TRY_TO(TraverseStmt(E)); + } + } return true; } @@ -3327,6 +3373,12 @@ bool RecursiveASTVisitor::VisitOMPFlushClause(OMPFlushClause *C) { return true; } +template +bool RecursiveASTVisitor::VisitOMPDepobjClause(OMPDepobjClause *C) { + TRY_TO(TraverseStmt(C->getDepobj())); + return true; +} + template bool RecursiveASTVisitor::VisitOMPDependClause(OMPDependClause *C) { TRY_TO(VisitOMPClauseList(C)); @@ -3425,6 +3477,13 @@ bool RecursiveASTVisitor::VisitOMPUseDevicePtrClause( return true; } +template +bool RecursiveASTVisitor::VisitOMPUseDeviceAddrClause( + OMPUseDeviceAddrClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + template bool RecursiveASTVisitor::VisitOMPIsDevicePtrClause( OMPIsDevicePtrClause *C) { @@ -3442,6 +3501,37 @@ bool RecursiveASTVisitor::VisitOMPNontemporalClause( return true; } +template +bool RecursiveASTVisitor::VisitOMPOrderClause(OMPOrderClause *) { + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPDetachClause(OMPDetachClause *C) { + TRY_TO(TraverseStmt(C->getEventHandler())); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPUsesAllocatorsClause( + OMPUsesAllocatorsClause *C) { + for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { + const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I); + TRY_TO(TraverseStmt(Data.Allocator)); + TRY_TO(TraverseStmt(Data.AllocatorTraits)); + } + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPAffinityClause( + OMPAffinityClause *C) { + TRY_TO(TraverseStmt(C->getModifier())); + for (Expr *E : C->varlists()) + TRY_TO(TraverseStmt(E)); + return true; +} + // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods // returning decls or qualtypes or nestednamespecifier -- though I'm diff --git a/gnu/llvm/clang/include/clang/AST/Stmt.h b/gnu/llvm/clang/include/clang/AST/Stmt.h index 3aa2745937b..d3fad58fcf5 100644 --- a/gnu/llvm/clang/include/clang/AST/Stmt.h +++ b/gnu/llvm/clang/include/clang/AST/Stmt.h @@ -14,12 +14,14 @@ #define LLVM_CLANG_AST_STMT_H #include "clang/AST/DeclGroup.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/StmtIterator.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" @@ -98,14 +100,8 @@ protected: /// The statement class. unsigned sClass : 8; - - /// This bit is set only for the Stmts that are the structured-block of - /// OpenMP executable directives. Directives that have a structured block - /// are called "non-standalone" directives. - /// I.e. those returned by OMPExecutableDirective::getStructuredBlock(). - unsigned IsOMPStructuredBlock : 1; }; - enum { NumStmtBits = 9 }; + enum { NumStmtBits = 8 }; class NullStmtBitfields { friend class ASTStmtReader; @@ -315,12 +311,9 @@ protected: unsigned ValueKind : 2; unsigned ObjectKind : 3; - unsigned TypeDependent : 1; - unsigned ValueDependent : 1; - unsigned InstantiationDependent : 1; - unsigned ContainsUnexpandedParameterPack : 1; + unsigned /*ExprDependence*/ Dependent : llvm::BitWidth; }; - enum { NumExprBits = NumStmtBits + 9 }; + enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth }; class ConstantExprBitfields { friend class ASTStmtReader; @@ -329,24 +322,27 @@ protected: unsigned : NumExprBits; - /// The kind of result that is trail-allocated. + /// The kind of result that is tail-allocated. unsigned ResultKind : 2; - /// Kind of Result as defined by APValue::Kind + /// The kind of Result as defined by APValue::Kind. unsigned APValueKind : 4; - /// When ResultKind == RSK_Int64. whether the trail-allocated integer is - /// signed. + /// When ResultKind == RSK_Int64, true if the tail-allocated integer is + /// unsigned. unsigned IsUnsigned : 1; - /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated - /// integer. 7 bits because it is the minimal number of bit to represent a - /// value from 0 to 64 (the size of the trail-allocated number). + /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated + /// integer. 7 bits because it is the minimal number of bits to represent a + /// value from 0 to 64 (the size of the tail-allocated integer). unsigned BitWidth : 7; - /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the - /// destructor on the trail-allocated APValue. + /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the + /// tail-allocated APValue. unsigned HasCleanup : 1; + + /// True if this ConstantExpr was created for immediate invocation. + unsigned IsImmediateInvocation : 1; }; class PredefinedExprBitfields { @@ -431,6 +427,11 @@ protected: unsigned Opc : 5; unsigned CanOverflow : 1; + // + /// This is only meaningful for operations on floating point + /// types when additional values need to be in trailing storage. + /// It is 0 otherwise. + unsigned HasFPFeatures : 1; SourceLocation Loc; }; @@ -444,8 +445,9 @@ protected: unsigned IsType : 1; // true if operand is a type, false if an expression. }; - class ArraySubscriptExprBitfields { + class ArrayOrMatrixSubscriptExprBitfields { friend class ArraySubscriptExpr; + friend class MatrixSubscriptExpr; unsigned : NumExprBits; @@ -529,8 +531,9 @@ protected: unsigned Opc : 6; /// This is only meaningful for operations on floating point - /// types and 0 otherwise. - unsigned FPFeatures : 3; + /// types when additional values need to be in trailing storage. + /// It is 0 otherwise. + unsigned HasFPFeatures : 1; SourceLocation OpLoc; }; @@ -611,9 +614,6 @@ protected: /// The kind of this overloaded operator. One of the enumerator /// value of OverloadedOperatorKind. unsigned OperatorKind : 6; - - // Only meaningful for floating point types. - unsigned FPFeatures : 3; }; class CXXRewrittenBinaryOperatorBitfields { @@ -772,8 +772,10 @@ protected: /// the trait evaluated true or false. unsigned Value : 1; - /// The number of arguments to this type trait. - unsigned NumArgs : 32 - 8 - 1 - NumExprBits; + /// The number of arguments to this type trait. According to [implimits] + /// 8 bits would be enough, but we require (and test for) at least 16 bits + /// to mirror FunctionType. + unsigned NumArgs; }; class DependentScopeDeclRefExprBitfields { @@ -922,6 +924,28 @@ protected: SourceLocation NameLoc; }; + class LambdaExprBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class LambdaExpr; + + unsigned : NumExprBits; + + /// The default capture kind, which is a value of type + /// LambdaCaptureDefault. + unsigned CaptureDefault : 2; + + /// Whether this lambda had an explicit parameter list vs. an + /// implicit (and empty) parameter list. + unsigned ExplicitParams : 1; + + /// Whether this lambda had the result type explicitly specified. + unsigned ExplicitResultType : 1; + + /// The number of captures. + unsigned NumCaptures : 16; + }; + class RequiresExprBitfields { friend class ASTStmtReader; friend class ASTStmtWriter; @@ -997,7 +1021,7 @@ protected: CharacterLiteralBitfields CharacterLiteralBits; UnaryOperatorBitfields UnaryOperatorBits; UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; - ArraySubscriptExprBitfields ArraySubscriptExprBits; + ArrayOrMatrixSubscriptExprBitfields ArrayOrMatrixSubscriptExprBits; CallExprBitfields CallExprBits; MemberExprBitfields MemberExprBits; CastExprBitfields CastExprBits; @@ -1034,6 +1058,7 @@ protected: UnresolvedMemberExprBitfields UnresolvedMemberExprBits; CXXNoexceptExprBitfields CXXNoexceptExprBits; SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits; + LambdaExprBitfields LambdaExprBits; RequiresExprBitfields RequiresExprBits; // C++ Coroutines TS expressions @@ -1117,7 +1142,6 @@ public: static_assert(sizeof(*this) % alignof(void *) == 0, "Insufficient alignment!"); StmtBits.sClass = SC; - StmtBits.IsOMPStructuredBlock = false; if (StatisticsEnabled) Stmt::addStmtClass(SC); } @@ -1127,11 +1151,6 @@ public: const char *getStmtClassName() const; - bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; } - void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) { - StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock; - } - /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. @@ -1147,9 +1166,7 @@ public: /// Dumps the specified AST fragment and all subtrees to /// \c llvm::errs(). void dump() const; - void dump(SourceManager &SM) const; - void dump(raw_ostream &OS, SourceManager &SM) const; - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; /// \return Unique reproducible object identifier int64_t getID(const ASTContext &Context) const; @@ -2260,6 +2277,8 @@ class WhileStmt final : public Stmt, enum { VarOffset = 0, BodyOffsetFromCond = 1 }; enum { NumMandatoryStmtPtr = 2 }; + SourceLocation LParenLoc, RParenLoc; + unsigned varOffset() const { return VarOffset; } unsigned condOffset() const { return VarOffset + hasVarStorage(); } unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; } @@ -2270,7 +2289,8 @@ class WhileStmt final : public Stmt, /// Build a while statement. WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, - SourceLocation WL); + SourceLocation WL, SourceLocation LParenLoc, + SourceLocation RParenLoc); /// Build an empty while statement. explicit WhileStmt(EmptyShell Empty, bool HasVar); @@ -2278,7 +2298,8 @@ class WhileStmt final : public Stmt, public: /// Create a while statement. static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, - Stmt *Body, SourceLocation WL); + Stmt *Body, SourceLocation WL, + SourceLocation LParenLoc, SourceLocation RParenLoc); /// Create an empty while statement optionally with storage for /// a condition variable. @@ -2342,6 +2363,11 @@ public: SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; } void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; } + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + SourceLocation getBeginLoc() const { return getWhileLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { return getBody()->getEndLoc(); @@ -3044,7 +3070,7 @@ public: } IdentifierInfo *getLabelIdentifier(unsigned i) const { - return Names[i + NumInputs]; + return Names[i + NumOutputs + NumInputs]; } AddrLabelExpr *getLabelExpr(unsigned i) const; @@ -3055,11 +3081,11 @@ public: using labels_const_range = llvm::iterator_range; labels_iterator begin_labels() { - return &Exprs[0] + NumInputs; + return &Exprs[0] + NumOutputs + NumInputs; } labels_iterator end_labels() { - return &Exprs[0] + NumInputs + NumLabels; + return &Exprs[0] + NumOutputs + NumInputs + NumLabels; } labels_range labels() { @@ -3067,11 +3093,11 @@ public: } const_labels_iterator begin_labels() const { - return &Exprs[0] + NumInputs; + return &Exprs[0] + NumOutputs + NumInputs; } const_labels_iterator end_labels() const { - return &Exprs[0] + NumInputs + NumLabels; + return &Exprs[0] + NumOutputs + NumInputs + NumLabels; } labels_const_range labels() const { diff --git a/gnu/llvm/clang/include/clang/AST/StmtOpenMP.h b/gnu/llvm/clang/include/clang/AST/StmtOpenMP.h index 65f0afece22..bd87eafc903 100644 --- a/gnu/llvm/clang/include/clang/AST/StmtOpenMP.h +++ b/gnu/llvm/clang/include/clang/AST/StmtOpenMP.h @@ -356,6 +356,9 @@ public: /// class OMPParallelDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel; @@ -381,6 +384,9 @@ class OMPParallelDirective : public OMPExecutableDirective { SourceLocation(), NumClauses, 1), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -392,11 +398,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *AssociatedStmt, bool HasCancel); + ArrayRef Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a N clauses. /// @@ -406,6 +415,10 @@ public: static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1258,7 +1271,9 @@ public: /// class OMPForDirective : public OMPLoopDirective { friend class ASTStmtReader; - + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current directive has inner cancel directive. bool HasCancel; @@ -1286,6 +1301,9 @@ class OMPForDirective : public OMPLoopDirective { NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1299,13 +1317,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner cancel directive. /// static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, - bool HasCancel); + Expr *TaskRedRef, bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1317,6 +1337,10 @@ public: static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1403,6 +1427,9 @@ public: class OMPSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current directive has inner cancel directive. bool HasCancel; @@ -1429,6 +1456,9 @@ class OMPSectionsDirective : public OMPExecutableDirective { SourceLocation(), NumClauses, 1), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1440,11 +1470,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner directive. /// static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *AssociatedStmt, bool HasCancel); + ArrayRef Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1455,6 +1488,10 @@ public: static OMPSectionsDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1715,6 +1752,9 @@ public: class OMPParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current region has inner cancel directive. bool HasCancel; @@ -1743,6 +1783,9 @@ class OMPParallelForDirective : public OMPLoopDirective { SourceLocation(), CollapsedNum, NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1756,12 +1799,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner cancel directive. /// static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1775,6 +1821,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1863,6 +1913,10 @@ public: class OMPParallelMasterDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; + OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelMasterDirectiveClass, @@ -1875,6 +1929,9 @@ class OMPParallelMasterDirective : public OMPExecutableDirective { SourceLocation(), SourceLocation(), NumClauses, 1) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + public: /// Creates directive with a list of \a Clauses. /// @@ -1883,10 +1940,12 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *AssociatedStmt); + ArrayRef Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1897,6 +1956,10 @@ public: static OMPParallelMasterDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelMasterDirectiveClass; } @@ -1914,6 +1977,9 @@ public: class OMPParallelSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current directive has inner cancel directive. bool HasCancel; @@ -1941,6 +2007,9 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective { 1), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1952,11 +2021,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner cancel directive. /// static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *AssociatedStmt, bool HasCancel); + ArrayRef Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1967,6 +2039,10 @@ public: static OMPParallelSectionsDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -2314,6 +2390,64 @@ public: } }; +/// This represents '#pragma omp depobj' directive. +/// +/// \code +/// #pragma omp depobj(a) depend(in:x,y) +/// \endcode +/// In this example directive '#pragma omp depobj' initializes a depobj object +/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. +class OMPDepobjDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPDepobjDirectiveClass, + llvm::omp::OMPD_depobj, StartLoc, EndLoc, + NumClauses, 0) {} + + /// Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPDepobjDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPDepobjDirectiveClass, + llvm::omp::OMPD_depobj, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// + static OMPDepobjDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPDepobjDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDepobjDirectiveClass; + } +}; + /// This represents '#pragma omp ordered' directive. /// /// \code @@ -2747,6 +2881,12 @@ public: /// class OMPTargetParallelDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; + /// true if the construct has inner cancel directive. + bool HasCancel = false; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -2769,6 +2909,11 @@ class OMPTargetParallelDirective : public OMPExecutableDirective { SourceLocation(), SourceLocation(), NumClauses, /*NumChildren=*/1) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } + public: /// Creates directive with a list of \a Clauses. /// @@ -2777,10 +2922,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *AssociatedStmt); + ArrayRef Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -2791,6 +2940,13 @@ public: static OMPTargetParallelDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTargetParallelDirectiveClass; } @@ -2808,6 +2964,9 @@ public: class OMPTargetParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current region has inner cancel directive. bool HasCancel; @@ -2837,6 +2996,9 @@ class OMPTargetParallelForDirective : public OMPLoopDirective { SourceLocation(), CollapsedNum, NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -2850,12 +3012,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner cancel directive. /// static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -2869,6 +3034,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -3070,6 +3239,9 @@ public: /// class OMPTaskLoopDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -3081,7 +3253,8 @@ class OMPTaskLoopDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), + HasCancel(false) {} /// Build an empty directive. /// @@ -3091,7 +3264,11 @@ class OMPTaskLoopDirective : public OMPLoopDirective { explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3103,11 +3280,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3120,6 +3298,9 @@ public: unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTaskLoopDirectiveClass; } @@ -3203,6 +3384,9 @@ public: /// class OMPMasterTaskLoopDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -3214,7 +3398,8 @@ class OMPMasterTaskLoopDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), + HasCancel(false) {} /// Build an empty directive. /// @@ -3225,7 +3410,11 @@ class OMPMasterTaskLoopDirective : public OMPLoopDirective { unsigned NumClauses) : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, llvm::omp::OMPD_master_taskloop, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3237,11 +3426,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3255,6 +3445,9 @@ public: unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; } @@ -3339,6 +3532,9 @@ public: /// class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -3351,7 +3547,8 @@ class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, llvm::omp::OMPD_parallel_master_taskloop, StartLoc, - EndLoc, CollapsedNum, NumClauses) {} + EndLoc, CollapsedNum, NumClauses), + HasCancel(false) {} /// Build an empty directive. /// @@ -3363,7 +3560,11 @@ class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, llvm::omp::OMPD_parallel_master_taskloop, SourceLocation(), SourceLocation(), CollapsedNum, - NumClauses) {} + NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3375,11 +3576,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPParallelMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3393,6 +3595,9 @@ public: unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; } @@ -3605,6 +3810,9 @@ public: /// class OMPDistributeParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel = false; @@ -3636,6 +3844,9 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective { NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -3649,12 +3860,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3668,6 +3882,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -4170,6 +4388,9 @@ public: /// class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel = false; @@ -4202,6 +4423,9 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -4215,12 +4439,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses clauses. /// @@ -4232,6 +4459,10 @@ public: CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -4379,6 +4610,9 @@ public: class OMPTargetTeamsDistributeParallelForDirective final : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel = false; @@ -4412,6 +4646,9 @@ class OMPTargetTeamsDistributeParallelForDirective final SourceLocation(), SourceLocation(), CollapsedNum, NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -4425,12 +4662,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses clauses. /// @@ -4442,6 +4682,10 @@ public: CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -4594,6 +4838,63 @@ public: } }; +/// This represents '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan inclusive(a) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'inclusive' with +/// list item 'a'. +class OMPScanDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPScanDirectiveClass, + llvm::omp::OMPD_scan, StartLoc, EndLoc, + NumClauses, 0) {} + + /// Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPScanDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPScanDirectiveClass, + llvm::omp::OMPD_scan, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses (only single OMPFlushClause clause is + /// allowed). + /// + static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPScanDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/gnu/llvm/clang/include/clang/AST/TemplateBase.h b/gnu/llvm/clang/include/clang/AST/TemplateBase.h index 93f7b62b8ae..51fd8ba5103 100644 --- a/gnu/llvm/clang/include/clang/AST/TemplateBase.h +++ b/gnu/llvm/clang/include/clang/AST/TemplateBase.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H #define LLVM_CLANG_AST_TEMPLATEBASE_H +#include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -81,8 +82,7 @@ public: /// The template argument is an expression, and we've not resolved it to one /// of the other forms yet, either because it's dependent or because we're /// representing a non-canonical template argument (for instance, in a - /// TemplateSpecializationType). Also used to represent a non-dependent - /// __uuidof expression (a Microsoft extension). + /// TemplateSpecializationType). Expression, /// The template argument is actually a parameter pack. Arguments are stored @@ -236,6 +236,8 @@ public: /// Determine whether this template argument has no value. bool isNull() const { return getKind() == Null; } + TemplateArgumentDependence getDependence() const; + /// Whether this template argument is dependent on a template /// parameter such that its result can change from one instantiation to /// another. @@ -666,11 +668,13 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo { void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, TemplateArgumentLoc *OutArgArray); + // FIXME: The parameter Deps is the result populated by this method, the + // caller doesn't need it since it is populated by computeDependence. remove + // it. void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, - TemplateArgumentLoc *OutArgArray, bool &Dependent, - bool &InstantiationDependent, - bool &ContainsUnexpandedParameterPack); + TemplateArgumentLoc *OutArgArray, + TemplateArgumentDependence &Deps); void initializeFrom(SourceLocation TemplateKWLoc); void copyInto(const TemplateArgumentLoc *ArgArray, diff --git a/gnu/llvm/clang/include/clang/AST/TemplateName.h b/gnu/llvm/clang/include/clang/AST/TemplateName.h index cbbcbf6af8a..9bcf2838dcf 100644 --- a/gnu/llvm/clang/include/clang/AST/TemplateName.h +++ b/gnu/llvm/clang/include/clang/AST/TemplateName.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H +#include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" @@ -295,6 +296,8 @@ public: /// the template, including any default template arguments. TemplateName getNameToSubstitute() const; + TemplateNameDependence getDependence() const; + /// Determines whether this is a dependent template name. bool isDependent() const; @@ -559,7 +562,7 @@ struct PointerLikeTypeTraits { } // No bits are available! - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm. diff --git a/gnu/llvm/clang/include/clang/AST/TextNodeDumper.h b/gnu/llvm/clang/include/clang/AST/TextNodeDumper.h index d293ea190aa..b4cfb5a380d 100644 --- a/gnu/llvm/clang/include/clang/AST/TextNodeDumper.h +++ b/gnu/llvm/clang/include/clang/AST/TextNodeDumper.h @@ -22,10 +22,13 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeVisitor.h" namespace clang { +class APValue; + class TextTreeStructure { raw_ostream &OS; const bool ShowColors; @@ -68,7 +71,7 @@ public: // We need to capture an owning-string in the lambda because the lambda // is invoked in a deferred manner. - std::string LabelStr = Label; + std::string LabelStr(Label); auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) { // Print out the appropriate tree structure and work out the prefix for // children of this node. For instance: @@ -139,19 +142,29 @@ class TextNodeDumper const char *LastLocFilename = ""; unsigned LastLocLine = ~0U; - const SourceManager *SM; + /// \p Context, \p SM, and \p Traits can be null. This is because we want + /// to be able to call \p dump() in a debugger without having to pass the + /// \p ASTContext to \p dump. Not all parts of the AST dump output will be + /// available without the \p ASTContext. + const ASTContext *Context = nullptr; + const SourceManager *SM = nullptr; /// The policy to use for printing; can be defaulted. - PrintingPolicy PrintPolicy; + PrintingPolicy PrintPolicy = LangOptions(); - const comments::CommandTraits *Traits; + const comments::CommandTraits *Traits = nullptr; const char *getCommandName(unsigned CommandID); + void dumpAPValueChildren(const APValue &Value, QualType Ty, + const APValue &(*IdxToChildFun)(const APValue &, + unsigned), + unsigned NumChildren, StringRef LabelSingular, + StringRef LabelPlurial); + public: - TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM, - const PrintingPolicy &PrintPolicy, - const comments::CommandTraits *Traits); + TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors); + TextNodeDumper(raw_ostream &OS, bool ShowColors); void Visit(const comments::Comment *C, const comments::FullComment *FC); @@ -176,6 +189,8 @@ public: void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); @@ -184,6 +199,7 @@ public: void dumpBareDeclRef(const Decl *D); void dumpName(const NamedDecl *ND); void dumpAccessSpecifier(AccessSpecifier AS); + void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C); void dumpDeclRef(const Decl *D, StringRef Label = {}); @@ -230,6 +246,7 @@ public: void VisitCaseStmt(const CaseStmt *Node); void VisitConstantExpr(const ConstantExpr *Node); void VisitCallExpr(const CallExpr *Node); + void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node); void VisitCastExpr(const CastExpr *Node); void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); @@ -257,6 +274,9 @@ public: void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); void VisitCXXNewExpr(const CXXNewExpr *Node); void VisitCXXDeleteExpr(const CXXDeleteExpr *Node); + void VisitTypeTraitExpr(const TypeTraitExpr *Node); + void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node); + void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node); void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); void VisitExprWithCleanups(const ExprWithCleanups *Node); void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); @@ -273,6 +293,7 @@ public: void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); + void VisitOMPIteratorExpr(const OMPIteratorExpr *Node); void VisitRValueReferenceType(const ReferenceType *T); void VisitArrayType(const ArrayType *T); diff --git a/gnu/llvm/clang/include/clang/AST/Type.h b/gnu/llvm/clang/include/clang/AST/Type.h index abc8136653f..0fc50e0e799 100644 --- a/gnu/llvm/clang/include/clang/AST/Type.h +++ b/gnu/llvm/clang/include/clang/AST/Type.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_AST_TYPE_H #define LLVM_CLANG_AST_TYPE_H +#include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/Basic/AddressSpaces.h" @@ -44,8 +45,8 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/PointerLikeTypeTraits.h" -#include "llvm/Support/type_traits.h" #include "llvm/Support/TrailingObjects.h" +#include "llvm/Support/type_traits.h" #include #include #include @@ -86,7 +87,7 @@ namespace llvm { return static_cast< ::clang::Type*>(P); } - enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; + static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; }; template<> @@ -97,7 +98,7 @@ namespace llvm { return static_cast< ::clang::ExtQuals*>(P); } - enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; + static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; }; } // namespace llvm @@ -943,6 +944,12 @@ public: /// from non-class types (in C++) or all types (in C). QualType getNonLValueExprType(const ASTContext &Context) const; + /// Remove an outer pack expansion type (if any) from this type. Used as part + /// of converting the type of a declaration to the type of an expression that + /// references that expression. It's meaningless for an expression to have a + /// pack expansion type. + QualType getNonPackExpansionType() const; + /// Return the specified type with any "sugar" removed from /// the type. This takes off typedefs, typeof's etc. If the outer level of /// the type is already concrete, it returns it unmodified. This is similar @@ -1051,7 +1058,7 @@ public: void dump(const char *s) const; void dump() const; - void dump(llvm::raw_ostream &OS) const; + void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(getAsOpaquePtr()); @@ -1063,6 +1070,21 @@ public: /// Return the address space of this type. inline LangAS getAddressSpace() const; + /// Returns true if address space qualifiers overlap with T address space + /// qualifiers. + /// OpenCL C defines conversion rules for pointers to different address spaces + /// and notion of overlapping address spaces. + /// CL1.1 or CL1.2: + /// address spaces overlap iff they are they same. + /// OpenCL C v2.0 s6.5.5 adds: + /// __generic overlaps with any address space except for __constant. + bool isAddressSpaceOverlapping(QualType T) const { + Qualifiers Q = getQualifiers(); + Qualifiers TQ = T.getQualifiers(); + // Address spaces overlap if at least one of them is a superset of another + return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q); + } + /// Returns gc attribute of this type. inline Qualifiers::GC getObjCGCAttr() const; @@ -1296,7 +1318,7 @@ struct PointerLikeTypeTraits { } // Various qualifiers go in low bits. - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm @@ -1465,19 +1487,8 @@ private: /// TypeClass bitfield - Enum that specifies what subclass this belongs to. unsigned TC : 8; - /// Whether this type is a dependent type (C++ [temp.dep.type]). - unsigned Dependent : 1; - - /// Whether this type somehow involves a template parameter, even - /// if the resolution of the type does not depend on a template parameter. - unsigned InstantiationDependent : 1; - - /// Whether this type is a variably-modified type (C99 6.7.5). - unsigned VariablyModified : 1; - - /// Whether this type contains an unexpanded parameter pack - /// (for C++11 variadic templates). - unsigned ContainsUnexpandedParameterPack : 1; + /// Store information on the type dependency. + unsigned Dependence : llvm::BitWidth; /// True if the cache (i.e. the bitfields here starting with /// 'Cache') is valid. @@ -1506,7 +1517,7 @@ private: return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 18 }; + enum { NumTypeBits = 8 + llvm::BitWidth + 6 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields @@ -1556,7 +1567,7 @@ protected: /// Extra information which affects how the function is called, like /// regparm and the calling convention. - unsigned ExtInfo : 12; + unsigned ExtInfo : 13; /// The ref-qualifier associated with a \c FunctionProtoType. /// @@ -1660,11 +1671,21 @@ protected: /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. unsigned VecKind : 3; - /// The number of elements in the vector. - unsigned NumElements : 29 - NumTypeBits; + uint32_t NumElements; + }; + + class ConstantMatrixTypeBitfields { + friend class ConstantMatrixType; - enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; + 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 { @@ -1776,6 +1797,7 @@ protected: TypeWithKeywordBitfields TypeWithKeywordBits; ElaboratedTypeBitfields ElaboratedTypeBits; VectorTypeBitfields VectorTypeBits; + ConstantMatrixTypeBitfields ConstantMatrixTypeBits; SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; DependentTemplateSpecializationTypeBitfields @@ -1828,16 +1850,11 @@ private: protected: friend class ASTContext; - Type(TypeClass tc, QualType canon, bool Dependent, - bool InstantiationDependent, bool VariablyModified, - bool ContainsUnexpandedParameterPack) + Type(TypeClass tc, QualType canon, TypeDependence Dependence) : ExtQualsTypeCommonBase(this, canon.isNull() ? QualType(this_(), 0) : canon) { TypeBits.TC = tc; - TypeBits.Dependent = Dependent; - TypeBits.InstantiationDependent = Dependent || InstantiationDependent; - TypeBits.VariablyModified = VariablyModified; - TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + TypeBits.Dependence = static_cast(Dependence); TypeBits.CacheValid = false; TypeBits.CachedLocalOrUnnamed = false; TypeBits.CachedLinkage = NoLinkage; @@ -1847,20 +1864,11 @@ protected: // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } - void setDependent(bool D = true) { - TypeBits.Dependent = D; - if (D) - TypeBits.InstantiationDependent = true; + void setDependence(TypeDependence D) { + TypeBits.Dependence = static_cast(D); } - void setInstantiationDependent(bool D = true) { - TypeBits.InstantiationDependent = D; } - - void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } - - void setContainsUnexpandedParameterPack(bool PP = true) { - TypeBits.ContainsUnexpandedParameterPack = PP; - } + void addDependence(TypeDependence D) { setDependence(getDependence() | D); } public: friend class ASTReader; @@ -1894,7 +1902,7 @@ public: /// /// Note that this routine does not specify which bool containsUnexpandedParameterPack() const { - return TypeBits.ContainsUnexpandedParameterPack; + return getDependence() & TypeDependence::UnexpandedPack; } /// Determines if this type would be canonical if it had no further @@ -1908,6 +1916,15 @@ public: /// or QualType::getSingleStepDesugaredType(const ASTContext&). QualType getLocallyUnqualifiedSingleStepDesugaredType() const; + /// As an extension, we classify types as one of "sized" or "sizeless"; + /// every type is one or the other. Standard types are all sized; + /// sizeless types are purely an extension. + /// + /// Sizeless types contain data with no specified size, alignment, + /// or layout. + bool isSizelessType() const; + bool isSizelessBuiltinType() const; + /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. @@ -1997,6 +2014,7 @@ public: bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isBFloat16Type() const; bool isFloat128Type() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) @@ -2039,6 +2057,8 @@ public: bool isComplexIntegerType() const; // GCC _Complex integer type. bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. + bool isMatrixType() const; // Matrix type. + bool isConstantMatrixType() const; // Constant matrix type. bool isDependentAddressSpaceType() const; // value-dependent address space qualifier bool isObjCObjectPointerType() const; // pointer to ObjC object bool isObjCRetainableType() const; // ObjC object or block pointer @@ -2119,6 +2139,7 @@ public: bool isOCLExtOpaqueType() const; // Any OpenCL extension type bool isPipeType() const; // OpenCL pipe type + bool isExtIntType() const; // Extended Int Type bool isOpenCLSpecificType() const; // Any OpenCL specific type /// Determines if this type, which must satisfy @@ -2126,6 +2147,11 @@ public: /// than implicitly __strong. bool isObjCARCImplicitlyUnretainedType() const; + /// Check if the type is the CUDA device builtin surface type. + bool isCUDADeviceBuiltinSurfaceType() const; + /// Check if the type is the CUDA device builtin texture type. + bool isCUDADeviceBuiltinTextureType() const; + /// Return the implicit lifetime for this type, which must not be dependent. Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; @@ -2145,16 +2171,27 @@ public: /// Given that this is a scalar type, classify it. ScalarTypeKind getScalarTypeKind() const; + TypeDependence getDependence() const { + return static_cast(TypeBits.Dependence); + } + + /// Whether this type is an error type. + bool containsErrors() const { + return getDependence() & TypeDependence::Error; + } + /// Whether this type is a dependent type, meaning that its definition /// somehow depends on a template parameter (C++ [temp.dep.type]). - bool isDependentType() const { return TypeBits.Dependent; } + bool isDependentType() const { + return getDependence() & TypeDependence::Dependent; + } /// Determine whether this type is an instantiation-dependent type, /// meaning that the type involves a template parameter (even if the /// definition does not actually depend on the type substituted for that /// template parameter). bool isInstantiationDependentType() const { - return TypeBits.InstantiationDependent; + return getDependence() & TypeDependence::Instantiation; } /// Determine whether this type is an undeduced type, meaning that @@ -2163,7 +2200,9 @@ public: bool isUndeducedType() const; /// Whether this type is a variably-modified type (C99 6.7.5). - bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } + bool isVariablyModifiedType() const { + return getDependence() & TypeDependence::VariablyModified; + } /// Whether this type involves a variable-length array type /// with a definite size. @@ -2432,7 +2471,7 @@ public: CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h void dump() const; - void dump(llvm::raw_ostream &OS) const; + void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; }; /// This will check for a TypedefType by removing any existing sugar @@ -2484,10 +2523,9 @@ private: friend class ASTContext; // ASTContext creates these. BuiltinType(Kind K) - : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), - /*InstantiationDependent=*/(K == Dependent), - /*VariablyModified=*/false, - /*Unexpanded parameter pack=*/false) { + : Type(Builtin, QualType(), + K == Dependent ? TypeDependence::DependentInstantiation + : TypeDependence::None) { BuiltinTypeBits.Kind = K; } @@ -2557,10 +2595,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode { QualType ElementType; ComplexType(QualType Element, QualType CanonicalPtr) - : Type(Complex, CanonicalPtr, Element->isDependentType(), - Element->isInstantiationDependentType(), - Element->isVariablyModifiedType(), - Element->containsUnexpandedParameterPack()), + : Type(Complex, CanonicalPtr, Element->getDependence()), ElementType(Element) {} public: @@ -2587,11 +2622,7 @@ class ParenType : public Type, public llvm::FoldingSetNode { QualType Inner; ParenType(QualType InnerType, QualType CanonType) - : Type(Paren, CanonType, InnerType->isDependentType(), - InnerType->isInstantiationDependentType(), - InnerType->isVariablyModifiedType(), - InnerType->containsUnexpandedParameterPack()), - Inner(InnerType) {} + : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} public: QualType getInnerType() const { return Inner; } @@ -2617,31 +2648,12 @@ class PointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; PointerType(QualType Pointee, QualType CanonicalPtr) - : Type(Pointer, CanonicalPtr, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(Pointer, CanonicalPtr, Pointee->getDependence()), PointeeType(Pointee) {} public: QualType getPointeeType() const { return PointeeType; } - /// Returns true if address spaces of pointers overlap. - /// OpenCL v2.0 defines conversion rules for pointers to different - /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping - /// address spaces. - /// CL1.1 or CL1.2: - /// address spaces overlap iff they are they same. - /// CL2.0 adds: - /// __generic overlaps with any address space except for __constant. - bool isAddressSpaceOverlapping(const PointerType &other) const { - Qualifiers thisQuals = PointeeType.getQualifiers(); - Qualifiers otherQuals = other.getPointeeType().getQualifiers(); - // Address spaces overlap if at least one of them is a superset of another - return thisQuals.isAddressSpaceSupersetOf(otherQuals) || - otherQuals.isAddressSpaceSupersetOf(thisQuals); - } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2668,10 +2680,7 @@ protected: AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, QualType CanonicalPtr) - : Type(TC, CanonicalPtr, OriginalTy->isDependentType(), - OriginalTy->isInstantiationDependentType(), - OriginalTy->isVariablyModifiedType(), - OriginalTy->containsUnexpandedParameterPack()), + : Type(TC, CanonicalPtr, OriginalTy->getDependence()), OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} public: @@ -2720,10 +2729,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; BlockPointerType(QualType Pointee, QualType CanonicalCls) - : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -2753,10 +2759,7 @@ class ReferenceType : public Type, public llvm::FoldingSetNode { protected: ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, bool SpelledAsLValue) - : Type(tc, CanonicalRef, Referencee->isDependentType(), - Referencee->isInstantiationDependentType(), - Referencee->isVariablyModifiedType(), - Referencee->containsUnexpandedParameterPack()), + : Type(tc, CanonicalRef, Referencee->getDependence()), PointeeType(Referencee) { ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); @@ -2841,13 +2844,9 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode { MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : Type(MemberPointer, CanonicalPtr, - Cls->isDependentType() || Pointee->isDependentType(), - (Cls->isInstantiationDependentType() || - Pointee->isInstantiationDependentType()), - Pointee->isVariablyModifiedType(), - (Cls->containsUnexpandedParameterPack() || - Pointee->containsUnexpandedParameterPack())), - PointeeType(Pointee), Class(Cls) {} + (Cls->getDependence() & ~TypeDependence::VariablyModified) | + Pointee->getDependence()), + PointeeType(Pointee), Class(Cls) {} public: QualType getPointeeType() const { return PointeeType; } @@ -3270,10 +3269,6 @@ public: QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } - static bool isVectorSizeTooLarge(unsigned NumElements) { - return NumElements > VectorTypeBitfields::MaxNumElements; - } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -3417,6 +3412,136 @@ public: } }; +/// Represents a matrix type, as defined in the Matrix Types clang extensions. +/// __attribute__((matrix_type(rows, columns))), where "rows" specifies +/// number of rows and "columns" specifies the number of columns. +class MatrixType : public Type, public llvm::FoldingSetNode { +protected: + friend class ASTContext; + + /// The element type of the matrix. + QualType ElementType; + + MatrixType(QualType ElementTy, QualType CanonElementTy); + + MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy, + const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr); + +public: + /// Returns type of the elements being stored in the matrix + QualType getElementType() const { return ElementType; } + + /// Valid elements types are the following: + /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types + /// and _Bool + /// * the standard floating types float or double + /// * a half-precision floating point type, if one is supported on the target + static bool isValidElementType(QualType T) { + return T->isDependentType() || + (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType()); + } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + static bool classof(const Type *T) { + return T->getTypeClass() == ConstantMatrix || + T->getTypeClass() == DependentSizedMatrix; + } +}; + +/// Represents a concrete matrix type with constant number of rows and columns +class ConstantMatrixType final : public MatrixType { +protected: + friend class ASTContext; + + /// The element type of the matrix. + QualType ElementType; + + ConstantMatrixType(QualType MatrixElementType, unsigned NRows, + unsigned NColumns, QualType CanonElementType); + + ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows, + unsigned NColumns, QualType CanonElementType); + +public: + /// Returns the number of rows in the matrix. + unsigned getNumRows() const { return ConstantMatrixTypeBits.NumRows; } + + /// Returns the number of columns in the matrix. + unsigned getNumColumns() const { return ConstantMatrixTypeBits.NumColumns; } + + /// Returns the number of elements required to embed the matrix into a vector. + unsigned getNumElementsFlattened() const { + return ConstantMatrixTypeBits.NumRows * ConstantMatrixTypeBits.NumColumns; + } + + /// Returns true if \p NumElements is a valid matrix dimension. + static bool isDimensionValid(uint64_t NumElements) { + return NumElements > 0 && + NumElements <= ConstantMatrixTypeBitfields::MaxElementsPerDimension; + } + + /// Returns the maximum number of elements per dimension. + static unsigned getMaxElementsPerDimension() { + return ConstantMatrixTypeBitfields::MaxElementsPerDimension; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getElementType(), getNumRows(), getNumColumns(), + getTypeClass()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, + unsigned NumRows, unsigned NumColumns, + TypeClass TypeClass) { + ID.AddPointer(ElementType.getAsOpaquePtr()); + ID.AddInteger(NumRows); + ID.AddInteger(NumColumns); + ID.AddInteger(TypeClass); + } + + static bool classof(const Type *T) { + return T->getTypeClass() == ConstantMatrix; + } +}; + +/// Represents a matrix type where the type and the number of rows and columns +/// is dependent on a template. +class DependentSizedMatrixType final : public MatrixType { + friend class ASTContext; + + const ASTContext &Context; + Expr *RowExpr; + Expr *ColumnExpr; + + SourceLocation loc; + + DependentSizedMatrixType(const ASTContext &Context, QualType ElementType, + QualType CanonicalType, Expr *RowExpr, + Expr *ColumnExpr, SourceLocation loc); + +public: + QualType getElementType() const { return ElementType; } + Expr *getRowExpr() const { return RowExpr; } + Expr *getColumnExpr() const { return ColumnExpr; } + SourceLocation getAttributeLoc() const { return loc; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + static bool classof(const Type *T) { + return T->getTypeClass() == DependentSizedMatrix; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + QualType ElementType, Expr *RowExpr, Expr *ColumnExpr); +}; + /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base /// class of FunctionNoProtoType and FunctionProtoType. class FunctionType : public Type { @@ -3533,39 +3658,41 @@ public: class ExtInfo { friend class FunctionType; - // Feel free to rearrange or add bits, but if you go over 12, - // you'll need to adjust both the Bits field below and - // Type::FunctionTypeBitfields. + // Feel free to rearrange or add bits, but if you go over 16, you'll need to + // adjust the Bits field below, and if you add bits, you'll need to adjust + // Type::FunctionTypeBitfields::ExtInfo as well. - // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck| - // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | + // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall| + // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 | // // regparm is either 0 (no regparm attribute) or the regparm value+1. enum { CallConvMask = 0x1F }; enum { NoReturnMask = 0x20 }; enum { ProducesResultMask = 0x40 }; enum { NoCallerSavedRegsMask = 0x80 }; - enum { NoCfCheckMask = 0x800 }; enum { - RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask | - NoCallerSavedRegsMask | NoCfCheckMask), + RegParmMask = 0x700, RegParmOffset = 8 - }; // Assumed to be the last field + }; + enum { NoCfCheckMask = 0x800 }; + enum { CmseNSCallMask = 0x1000 }; uint16_t Bits = CC_C; ExtInfo(unsigned Bits) : Bits(static_cast(Bits)) {} - public: - // Constructor with no defaults. Use this when you know that you - // have all the elements (when reading an AST file for example). - ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, - bool producesResult, bool noCallerSavedRegs, bool NoCfCheck) { - assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); - Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | - (producesResult ? ProducesResultMask : 0) | - (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | - (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | - (NoCfCheck ? NoCfCheckMask : 0); + public: + // Constructor with no defaults. Use this when you know that you + // have all the elements (when reading an AST file for example). + ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, + bool producesResult, bool noCallerSavedRegs, bool NoCfCheck, + bool cmseNSCall) { + assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); + Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | + (producesResult ? ProducesResultMask : 0) | + (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | + (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | + (NoCfCheck ? NoCfCheckMask : 0) | + (cmseNSCall ? CmseNSCallMask : 0); } // Constructor with all defaults. Use when for example creating a @@ -3578,9 +3705,10 @@ public: bool getNoReturn() const { return Bits & NoReturnMask; } bool getProducesResult() const { return Bits & ProducesResultMask; } + bool getCmseNSCall() const { return Bits & CmseNSCallMask; } bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } bool getNoCfCheck() const { return Bits & NoCfCheckMask; } - bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } + bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; } unsigned getRegParm() const { unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset; @@ -3615,6 +3743,13 @@ public: return ExtInfo(Bits & ~ProducesResultMask); } + ExtInfo withCmseNSCall(bool cmseNSCall) const { + if (cmseNSCall) + return ExtInfo(Bits | CmseNSCallMask); + else + return ExtInfo(Bits & ~CmseNSCallMask); + } + ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const { if (noCallerSavedRegs) return ExtInfo(Bits | NoCallerSavedRegsMask); @@ -3661,14 +3796,9 @@ public: }; protected: - FunctionType(TypeClass tc, QualType res, - QualType Canonical, bool Dependent, - bool InstantiationDependent, - bool VariablyModified, bool ContainsUnexpandedParameterPack, - ExtInfo Info) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack), - ResultType(res) { + FunctionType(TypeClass tc, QualType res, QualType Canonical, + TypeDependence Dependence, ExtInfo Info) + : Type(tc, Canonical, Dependence), ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; } @@ -3687,6 +3817,7 @@ public: /// type. bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } + bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); } CallingConv getCallConv() const { return getExtInfo().getCC(); } ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } @@ -3719,9 +3850,10 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) : FunctionType(FunctionNoProto, Result, Canonical, - /*Dependent=*/false, /*InstantiationDependent=*/false, - Result->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false, Info) {} + Result->getDependence() & + ~(TypeDependence::DependentInstantiation | + TypeDependence::UnexpandedPack), + Info) {} public: // No additional state past what FunctionType provides. @@ -4213,9 +4345,9 @@ class UnresolvedUsingType : public Type { UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) - : Type(UnresolvedUsing, QualType(), true, true, false, - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast(D)) {} + : Type(UnresolvedUsing, QualType(), + TypeDependence::DependentInstantiation), + Decl(const_cast(D)) {} public: UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } @@ -4244,11 +4376,8 @@ protected: friend class ASTContext; // ASTContext creates these. TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) - : Type(tc, can, can->isDependentType(), - can->isInstantiationDependentType(), - can->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast(D)) { + : Type(tc, can, can->getDependence() & ~TypeDependence::UnexpandedPack), + Decl(const_cast(D)) { assert(!isa(can) && "Invalid canonical type"); } @@ -4271,10 +4400,7 @@ class MacroQualifiedType : public Type { MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, const IdentifierInfo *MacroII) - : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(), - UnderlyingTy->isInstantiationDependentType(), - UnderlyingTy->isVariablyModifiedType(), - UnderlyingTy->containsUnexpandedParameterPack()), + : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), UnderlyingTy(UnderlyingTy), MacroII(MacroII) { assert(isa(UnderlyingTy) && "Expected a macro qualified type to only wrap attributed types."); @@ -4346,11 +4472,7 @@ class TypeOfType : public Type { QualType TOType; TypeOfType(QualType T, QualType can) - : Type(TypeOf, can, T->isDependentType(), - T->isInstantiationDependentType(), - T->isVariablyModifiedType(), - T->containsUnexpandedParameterPack()), - TOType(T) { + : Type(TypeOf, can, T->getDependence()), TOType(T) { assert(!isa(can) && "Invalid canonical type"); } @@ -4559,10 +4681,7 @@ private: AttributedType(QualType canon, attr::Kind attrKind, QualType modified, QualType equivalent) - : Type(Attributed, canon, equivalent->isDependentType(), - equivalent->isInstantiationDependentType(), - equivalent->isVariablyModifiedType(), - equivalent->containsUnexpandedParameterPack()), + : Type(Attributed, canon, equivalent->getDependence()), ModifiedType(modified), EquivalentType(equivalent) { AttributedTypeBits.AttrKind = attrKind; } @@ -4664,18 +4783,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { /// Build a non-canonical type. TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) - : Type(TemplateTypeParm, Canon, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - Canon->containsUnexpandedParameterPack()), + : Type(TemplateTypeParm, Canon, + TypeDependence::DependentInstantiation | + (Canon->getDependence() & TypeDependence::UnexpandedPack)), TTPDecl(TTPDecl) {} /// Build the canonical type. TemplateTypeParmType(unsigned D, unsigned I, bool PP) : Type(TemplateTypeParm, QualType(this, 0), - /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, PP) { + TypeDependence::DependentInstantiation | + (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) { CanTTPTInfo.Depth = D; CanTTPTInfo.Index = I; CanTTPTInfo.ParameterPack = PP; @@ -4732,10 +4849,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { const TemplateTypeParmType *Replaced; SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) - : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), - Canon->isInstantiationDependentType(), - Canon->isVariablyModifiedType(), - Canon->containsUnexpandedParameterPack()), + : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()), Replaced(Param) {} public: @@ -4832,23 +4946,16 @@ public: /// the latter case, it is also a dependent type. class DeducedType : public Type { protected: - DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent, - bool IsInstantiationDependent, bool ContainsParameterPack) + DeducedType(TypeClass TC, QualType DeducedAsType, + TypeDependence ExtraDependence) : Type(TC, // FIXME: Retain the sugared deduced type? DeducedAsType.isNull() ? QualType(this, 0) : DeducedAsType.getCanonicalType(), - IsDependent, IsInstantiationDependent, - /*VariablyModified=*/false, ContainsParameterPack) { - if (!DeducedAsType.isNull()) { - if (DeducedAsType->isDependentType()) - setDependent(); - if (DeducedAsType->isInstantiationDependentType()) - setInstantiationDependent(); - if (DeducedAsType->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); - } - } + ExtraDependence | (DeducedAsType.isNull() + ? TypeDependence::None + : DeducedAsType->getDependence() & + ~TypeDependence::VariablyModified)) {} public: bool isSugared() const { return !isCanonicalUnqualified(); } @@ -4877,7 +4984,7 @@ class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode { ConceptDecl *TypeConstraintConcept; AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent, bool IsDeducedAsPack, ConceptDecl *CD, + TypeDependence ExtraDependence, ConceptDecl *CD, ArrayRef TypeConstraintArgs); const TemplateArgument *getArgBuffer() const { @@ -4948,9 +5055,10 @@ class DeducedTemplateSpecializationType : public DeducedType, QualType DeducedAsType, bool IsDeducedAsDependent) : DeducedType(DeducedTemplateSpecialization, DeducedAsType, - IsDeducedAsDependent || Template.isDependent(), - IsDeducedAsDependent || Template.isInstantiationDependent(), - Template.containsUnexpandedParameterPack()), + toTypeDependence(Template.getDependence()) | + (IsDeducedAsDependent + ? TypeDependence::DependentInstantiation + : TypeDependence::None)), Template(Template) {} public: @@ -5152,10 +5260,8 @@ class InjectedClassNameType : public Type { QualType InjectedType; InjectedClassNameType(CXXRecordDecl *D, QualType TST) - : Type(InjectedClassName, QualType(), /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - /*ContainsUnexpandedParameterPack=*/false), + : Type(InjectedClassName, QualType(), + TypeDependence::DependentInstantiation), Decl(D), InjectedType(TST) { assert(isa(TST)); assert(!TST.hasQualifiers()); @@ -5234,11 +5340,8 @@ enum ElaboratedTypeKeyword { class TypeWithKeyword : public Type { protected: TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, - QualType Canonical, bool Dependent, - bool InstantiationDependent, bool VariablyModified, - bool ContainsUnexpandedParameterPack) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack) { + QualType Canonical, TypeDependence Dependence) + : Type(tc, Canonical, Dependence) { TypeWithKeywordBits.Keyword = Keyword; } @@ -5302,10 +5405,7 @@ class ElaboratedType final ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) : TypeWithKeyword(Keyword, Elaborated, CanonType, - NamedType->isDependentType(), - NamedType->isInstantiationDependentType(), - NamedType->isVariablyModifiedType(), - NamedType->containsUnexpandedParameterPack()), + NamedType->getDependence()), NNS(NNS), NamedType(NamedType) { ElaboratedTypeBits.HasOwnedTagDecl = false; if (OwnedTagDecl) { @@ -5376,10 +5476,9 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) - : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - NNS->containsUnexpandedParameterPack()), + : TypeWithKeyword(Keyword, DependentName, CanonType, + TypeDependence::DependentInstantiation | + toTypeDependence(NNS->getDependence())), NNS(NNS), Name(Name) {} public: @@ -5516,10 +5615,9 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { PackExpansionType(QualType Pattern, QualType Canon, Optional NumExpansions) - : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), - /*InstantiationDependent=*/true, - /*VariablyModified=*/Pattern->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), + : Type(PackExpansion, Canon, + (Pattern->getDependence() | TypeDependence::Instantiation) & + ~TypeDependence::UnexpandedPack), Pattern(Pattern) { PackExpansionTypeBits.NumExpansions = NumExpansions ? *NumExpansions + 1 : 0; @@ -5658,6 +5756,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, const ObjCTypeParamDecl *OTPDecl, + QualType CanonicalType, ArrayRef protocols); ObjCTypeParamDecl *getDecl() const { return OTPDecl; } @@ -5738,8 +5837,8 @@ protected: bool isKindOf); ObjCObjectType(enum Nonce_ObjCInterface) - : Type(ObjCInterface, QualType(), false, false, false, false), - BaseType(QualType(this_(), 0)) { + : Type(ObjCInterface, QualType(), TypeDependence::None), + BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; ObjCObjectTypeBits.NumTypeArgs = 0; ObjCObjectTypeBits.IsKindOf = 0; @@ -5954,11 +6053,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, - Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -6128,11 +6223,7 @@ class AtomicType : public Type, public llvm::FoldingSetNode { QualType ValueType; AtomicType(QualType ValTy, QualType Canonical) - : Type(Atomic, Canonical, ValTy->isDependentType(), - ValTy->isInstantiationDependentType(), - ValTy->isVariablyModifiedType(), - ValTy->containsUnexpandedParameterPack()), - ValueType(ValTy) {} + : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {} public: /// Gets the type contained by this atomic type, i.e. @@ -6163,10 +6254,7 @@ class PipeType : public Type, public llvm::FoldingSetNode { bool isRead; PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) - : Type(Pipe, CanonicalPtr, elemType->isDependentType(), - elemType->isInstantiationDependentType(), - elemType->isVariablyModifiedType(), - elemType->containsUnexpandedParameterPack()), + : Type(Pipe, CanonicalPtr, elemType->getDependence()), ElementType(elemType), isRead(isRead) {} public: @@ -6192,6 +6280,64 @@ public: bool isReadOnly() const { return isRead; } }; +/// A fixed int type of a specified bitwidth. +class ExtIntType final : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + unsigned IsUnsigned : 1; + unsigned NumBits : 24; + +protected: + ExtIntType(bool isUnsigned, unsigned NumBits); + +public: + bool isUnsigned() const { return IsUnsigned; } + bool isSigned() const { return !IsUnsigned; } + unsigned getNumBits() const { return NumBits; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, isUnsigned(), getNumBits()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned, + unsigned NumBits) { + ID.AddBoolean(IsUnsigned); + ID.AddInteger(NumBits); + } + + static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; } +}; + +class DependentExtIntType final : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + const ASTContext &Context; + llvm::PointerIntPair ExprAndUnsigned; + +protected: + DependentExtIntType(const ASTContext &Context, bool IsUnsigned, + Expr *NumBits); + +public: + bool isUnsigned() const; + bool isSigned() const { return !isUnsigned(); } + Expr *getNumBitsExpr() const; + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Context, isUnsigned(), getNumBitsExpr()); + } + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + bool IsUnsigned, Expr *NumBitsExpr); + + static bool classof(const Type *T) { + return T->getTypeClass() == DependentExtInt; + } +}; + /// A qualifier set is used to build a set of qualifiers. class QualifierCollector : public Qualifiers { public: @@ -6611,6 +6757,14 @@ inline bool Type::isExtVectorType() const { return isa(CanonicalType); } +inline bool Type::isMatrixType() const { + return isa(CanonicalType); +} + +inline bool Type::isConstantMatrixType() const { + return isa(CanonicalType); +} + inline bool Type::isDependentAddressSpaceType() const { return isa(CanonicalType); } @@ -6711,6 +6865,10 @@ inline bool Type::isPipeType() const { return isa(CanonicalType); } +inline bool Type::isExtIntType() const { + return isa(CanonicalType); +} + #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ inline bool Type::is##Id##Type() const { \ return isSpecificBuiltinType(BuiltinType::Id); \ @@ -6742,9 +6900,9 @@ inline bool Type::isTemplateTypeParmType() const { } inline bool Type::isSpecificBuiltinType(unsigned K) const { - if (const BuiltinType *BT = getAs()) - if (BT->getKind() == (BuiltinType::Kind) K) - return true; + if (const BuiltinType *BT = getAs()) { + return BT->getKind() == static_cast(K); + } return false; } @@ -6763,9 +6921,7 @@ inline const BuiltinType *Type::getAsPlaceholderType() const { inline bool Type::isSpecificPlaceholderType(unsigned K) const { assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)); - if (const auto *BT = dyn_cast(this)) - return (BT->getKind() == (BuiltinType::Kind) K); - return false; + return isSpecificBuiltinType(K); } inline bool Type::isNonOverloadPlaceholderType() const { @@ -6775,34 +6931,28 @@ inline bool Type::isNonOverloadPlaceholderType() const { } inline bool Type::isVoidType() const { - if (const auto *BT = dyn_cast(CanonicalType)) - return BT->getKind() == BuiltinType::Void; - return false; + return isSpecificBuiltinType(BuiltinType::Void); } inline bool Type::isHalfType() const { - if (const auto *BT = dyn_cast(CanonicalType)) - return BT->getKind() == BuiltinType::Half; // FIXME: Should we allow complex __fp16? Probably not. - return false; + return isSpecificBuiltinType(BuiltinType::Half); } inline bool Type::isFloat16Type() const { - if (const auto *BT = dyn_cast(CanonicalType)) - return BT->getKind() == BuiltinType::Float16; - return false; + return isSpecificBuiltinType(BuiltinType::Float16); +} + +inline bool Type::isBFloat16Type() const { + return isSpecificBuiltinType(BuiltinType::BFloat16); } inline bool Type::isFloat128Type() const { - if (const auto *BT = dyn_cast(CanonicalType)) - return BT->getKind() == BuiltinType::Float128; - return false; + return isSpecificBuiltinType(BuiltinType::Float128); } inline bool Type::isNullPtrType() const { - if (const auto *BT = getAs()) - return BT->getKind() == BuiltinType::NullPtr; - return false; + return isSpecificBuiltinType(BuiltinType::NullPtr); } bool IsEnumDeclComplete(EnumDecl *); @@ -6818,7 +6968,7 @@ inline bool Type::isIntegerType() const { return IsEnumDeclComplete(ET->getDecl()) && !IsEnumDeclScoped(ET->getDecl()); } - return false; + return isExtIntType(); } inline bool Type::isFixedPointType() const { @@ -6875,7 +7025,8 @@ inline bool Type::isScalarType() const { isa(CanonicalType) || isa(CanonicalType) || isa(CanonicalType) || - isa(CanonicalType); + isa(CanonicalType) || + isExtIntType(); } inline bool Type::isIntegralOrEnumerationType() const { @@ -6888,7 +7039,7 @@ inline bool Type::isIntegralOrEnumerationType() const { if (const auto *ET = dyn_cast(CanonicalType)) return IsEnumDeclComplete(ET->getDecl()); - return false; + return isExtIntType(); } inline bool Type::isBooleanType() const { diff --git a/gnu/llvm/clang/include/clang/AST/TypeLoc.h b/gnu/llvm/clang/include/clang/AST/TypeLoc.h index 3fc53d823c3..72cc8ef098e 100644 --- a/gnu/llvm/clang/include/clang/AST/TypeLoc.h +++ b/gnu/llvm/clang/include/clang/AST/TypeLoc.h @@ -1735,6 +1735,7 @@ public: void initializeLocal(ASTContext &Context, SourceLocation loc) { setAttrNameLoc(loc); + setAttrOperandParensRange(loc); setAttrOperandParensRange(SourceRange(loc)); setAttrExprOperand(getTypePtr()->getAddrSpaceExpr()); } @@ -1774,6 +1775,68 @@ class DependentSizedExtVectorTypeLoc : DependentSizedExtVectorType> { }; +struct MatrixTypeLocInfo { + SourceLocation AttrLoc; + SourceRange OperandParens; + Expr *RowOperand; + Expr *ColumnOperand; +}; + +class MatrixTypeLoc : public ConcreteTypeLoc { +public: + /// The location of the attribute name, i.e. + /// float __attribute__((matrix_type(4, 2))) + /// ^~~~~~~~~~~~~~~~~ + SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; } + void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; } + + /// The attribute's row operand, if it has one. + /// float __attribute__((matrix_type(4, 2))) + /// ^ + Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; } + void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; } + + /// The attribute's column operand, if it has one. + /// float __attribute__((matrix_type(4, 2))) + /// ^ + Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; } + void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; } + + /// The location of the parentheses around the operand, if there is + /// an operand. + /// float __attribute__((matrix_type(4, 2))) + /// ^ ^ + SourceRange getAttrOperandParensRange() const { + return getLocalData()->OperandParens; + } + void setAttrOperandParensRange(SourceRange range) { + getLocalData()->OperandParens = range; + } + + SourceRange getLocalSourceRange() const { + SourceRange range(getAttrNameLoc()); + range.setEnd(getAttrOperandParensRange().getEnd()); + return range; + } + + void initializeLocal(ASTContext &Context, SourceLocation loc) { + setAttrNameLoc(loc); + setAttrOperandParensRange(loc); + setAttrRowOperand(nullptr); + setAttrColumnOperand(nullptr); + } +}; + +class ConstantMatrixTypeLoc + : public InheritingConcreteTypeLoc {}; + +class DependentSizedMatrixTypeLoc + : public InheritingConcreteTypeLoc {}; + // FIXME: location of the '_Complex' keyword. class ComplexTypeLoc : public InheritingConcreteTypeLoc(); } +class ExtIntTypeLoc final + : public InheritingConcreteTypeLoc {}; +class DependentExtIntTypeLoc final + : public InheritingConcreteTypeLoc {}; } // namespace clang diff --git a/gnu/llvm/clang/include/clang/AST/TypeLocVisitor.h b/gnu/llvm/clang/include/clang/AST/TypeLocVisitor.h index ec780884e96..168e9ac532e 100644 --- a/gnu/llvm/clang/include/clang/AST/TypeLocVisitor.h +++ b/gnu/llvm/clang/include/clang/AST/TypeLocVisitor.h @@ -13,7 +13,6 @@ #define LLVM_CLANG_AST_TYPELOCVISITOR_H #include "clang/AST/TypeLoc.h" -#include "clang/AST/TypeVisitor.h" #include "llvm/Support/ErrorHandling.h" namespace clang { diff --git a/gnu/llvm/clang/include/clang/AST/TypeProperties.td b/gnu/llvm/clang/include/clang/AST/TypeProperties.td index 3cf56e5a562..4540ea0e195 100644 --- a/gnu/llvm/clang/include/clang/AST/TypeProperties.td +++ b/gnu/llvm/clang/include/clang/AST/TypeProperties.td @@ -224,6 +224,41 @@ let Class = DependentSizedExtVectorType in { }]>; } +let Class = MatrixType in { + def : Property<"elementType", QualType> { + let Read = [{ node->getElementType() }]; + } +} + +let Class = ConstantMatrixType in { + def : Property<"numRows", UInt32> { + let Read = [{ node->getNumRows() }]; + } + def : Property<"numColumns", UInt32> { + let Read = [{ node->getNumColumns() }]; + } + + def : Creator<[{ + return ctx.getConstantMatrixType(elementType, numRows, numColumns); + }]>; +} + +let Class = DependentSizedMatrixType in { + def : Property<"rows", ExprRef> { + let Read = [{ node->getRowExpr() }]; + } + def : Property<"columns", ExprRef> { + let Read = [{ node->getColumnExpr() }]; + } + def : Property<"attributeLoc", SourceLocation> { + let Read = [{ node->getAttributeLoc() }]; + } + + def : Creator<[{ + return ctx.getDependentSizedMatrixType(elementType, rows, columns, attributeLoc); + }]>; +} + let Class = FunctionType in { def : Property<"returnType", QualType> { let Read = [{ node->getReturnType() }]; @@ -249,13 +284,17 @@ let Class = FunctionType in { def : Property<"noCfCheck", Bool> { let Read = [{ node->getExtInfo().getNoCfCheck() }]; } + def : Property<"cmseNSCall", Bool> { + let Read = [{ node->getExtInfo().getCmseNSCall() }]; + } } let Class = FunctionNoProtoType in { def : Creator<[{ auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm, callingConvention, producesResult, - noCallerSavedRegs, noCfCheck); + noCallerSavedRegs, noCfCheck, + cmseNSCall); return ctx.getFunctionNoProtoType(returnType, extInfo); }]>; } @@ -288,7 +327,8 @@ let Class = FunctionProtoType in { def : Creator<[{ auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm, callingConvention, producesResult, - noCallerSavedRegs, noCfCheck); + noCallerSavedRegs, noCfCheck, + cmseNSCall); FunctionProtoType::ExtProtoInfo epi; epi.ExtInfo = extInfo; epi.Variadic = variadic; @@ -453,7 +493,9 @@ let Class = TagType in { let Class = EnumType in { def : Creator<[{ QualType result = ctx.getEnumType(cast(declaration)); - const_cast(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -462,7 +504,9 @@ let Class = RecordType in { def : Creator<[{ auto record = cast(declaration); QualType result = ctx.getRecordType(record); - const_cast(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -605,7 +649,9 @@ let Class = TemplateSpecializationType in { templateArguments, *underlyingType); } - const_cast(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -822,3 +868,28 @@ let Class = PipeType in { return ctx.getPipeType(elementType, isReadOnly); }]>; } + +let Class = ExtIntType in { + def : Property<"isUnsigned", Bool> { + let Read = [{ node->isUnsigned() }]; + } + def : Property <"numBits", UInt32> { + let Read = [{ node->getNumBits() }]; + } + + def : Creator<[{ + return ctx.getExtIntType(isUnsigned, numBits); + }]>; +} + +let Class = DependentExtIntType in { + def : Property<"isUnsigned", Bool> { + let Read = [{ node->isUnsigned() }]; + } + def : Property <"numBitsExpr", ExprRef> { + let Read = [{ node->getNumBitsExpr() }]; + } + def : Creator<[{ + return ctx.getDependentExtIntType(isUnsigned, numBitsExpr); + }]>; +} diff --git a/gnu/llvm/clang/include/clang/AST/VTableBuilder.h b/gnu/llvm/clang/include/clang/AST/VTableBuilder.h index 43c84292c09..241dd13f903 100644 --- a/gnu/llvm/clang/include/clang/AST/VTableBuilder.h +++ b/gnu/llvm/clang/include/clang/AST/VTableBuilder.h @@ -238,6 +238,11 @@ public: typedef llvm::DenseMap AddressPointsMapTy; + // Mapping between the VTable index and address point index. This is useful + // when you don't care about the base subobjects and only want the address + // point for a given vtable index. + typedef llvm::SmallVector AddressPointsIndexMapTy; + private: // Stores the component indices of the first component of each virtual table in // the virtual table group. To save a little memory in the common case where @@ -253,6 +258,9 @@ private: /// Address points for all vtables. AddressPointsMapTy AddressPoints; + /// Address points for all vtable indices. + AddressPointsIndexMapTy AddressPointIndices; + public: VTableLayout(ArrayRef VTableIndices, ArrayRef VTableComponents, @@ -277,6 +285,10 @@ public: return AddressPoints; } + const AddressPointsIndexMapTy &getAddressPointIndices() const { + return AddressPointIndices; + } + size_t getNumVTables() const { if (VTableIndices.empty()) return 1; @@ -342,6 +354,9 @@ public: } bool IsMicrosoftABI; + + /// Determine whether this function should be assigned a vtable slot. + static bool hasVtableSlot(const CXXMethodDecl *MD); }; class ItaniumVTableContext : public VTableContextBase { @@ -371,7 +386,17 @@ private: void computeVTableRelatedInformation(const CXXRecordDecl *RD) override; public: - ItaniumVTableContext(ASTContext &Context); + enum VTableComponentLayout { + /// Components in the vtable are pointers to other structs/functions. + Pointer, + + /// Components in the vtable are relative offsets between the vtable and the + /// other structs/functions. + Relative, + }; + + ItaniumVTableContext(ASTContext &Context, + VTableComponentLayout ComponentLayout = Pointer); ~ItaniumVTableContext() override; const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { @@ -402,6 +427,16 @@ public: static bool classof(const VTableContextBase *VT) { return !VT->isMicrosoft(); } + + VTableComponentLayout getVTableComponentLayout() const { + return ComponentLayout; + } + + bool isPointerLayout() const { return ComponentLayout == Pointer; } + bool isRelativeLayout() const { return ComponentLayout == Relative; } + +private: + VTableComponentLayout ComponentLayout; }; /// Holds information about the inheritance path to a virtual base or function diff --git a/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchFinder.h index f8160d552c0..0af98438ab5 100644 --- a/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchFinder.h @@ -182,10 +182,9 @@ public: /// /// @{ template void match(const T &Node, ASTContext &Context) { - match(clang::ast_type_traits::DynTypedNode::create(Node), Context); + match(clang::DynTypedNode::create(Node), Context); } - void match(const clang::ast_type_traits::DynTypedNode &Node, - ASTContext &Context); + void match(const clang::DynTypedNode &Node, ASTContext &Context); /// @} /// Finds all matches in the given AST. @@ -242,9 +241,8 @@ SmallVector match(MatcherT Matcher, const NodeT &Node, ASTContext &Context); template -SmallVector -match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, - ASTContext &Context); +SmallVector match(MatcherT Matcher, const DynTypedNode &Node, + ASTContext &Context); /// @} /// Returns the results of matching \p Matcher on the translation unit of @@ -283,9 +281,8 @@ public: } template -SmallVector -match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, - ASTContext &Context) { +SmallVector match(MatcherT Matcher, const DynTypedNode &Node, + ASTContext &Context) { internal::CollectMatchesCallback Callback; MatchFinder Finder; Finder.addMatcher(Matcher, &Callback); @@ -296,7 +293,7 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, template SmallVector match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) { - return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context); + return match(Matcher, DynTypedNode::create(Node), Context); } template @@ -310,8 +307,8 @@ match(MatcherT Matcher, ASTContext &Context) { } inline SmallVector -matchDynamic(internal::DynTypedMatcher Matcher, - const ast_type_traits::DynTypedNode &Node, ASTContext &Context) { +matchDynamic(internal::DynTypedMatcher Matcher, const DynTypedNode &Node, + ASTContext &Context) { internal::CollectMatchesCallback Callback; MatchFinder Finder; Finder.addDynamicMatcher(Matcher, &Callback); @@ -323,8 +320,7 @@ template SmallVector matchDynamic(internal::DynTypedMatcher Matcher, const NodeT &Node, ASTContext &Context) { - return matchDynamic(Matcher, ast_type_traits::DynTypedNode::create(Node), - Context); + return matchDynamic(Matcher, DynTypedNode::create(Node), Context); } inline SmallVector diff --git a/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchers.h b/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchers.h index 9a5888b7572..643419743a1 100644 --- a/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/gnu/llvm/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -47,6 +47,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Attr.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" @@ -59,6 +60,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/OperationKinds.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" @@ -71,6 +73,7 @@ #include "clang/ASTMatchers/ASTMatchersMacros.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" @@ -114,7 +117,7 @@ public: /// Type of mapping from binding identifiers to bound nodes. This type /// is an associative container with a key type of \c std::string and a value - /// type of \c clang::ast_type_traits::DynTypedNode + /// type of \c clang::DynTypedNode using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap; /// Retrieve mapping from binding identifiers to bound nodes. @@ -280,9 +283,10 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader, /// \endcode /// /// Usable as: Matcher, Matcher, Matcher -AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, - AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc), - std::string, RegExp) { +AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, + TypeLoc), + RegExp) { auto &SourceManager = Finder->getASTContext().getSourceManager(); auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc()); if (ExpansionLoc.isInvalid()) { @@ -295,8 +299,27 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, } auto Filename = FileEntry->getName(); - llvm::Regex RE(RegExp); - return RE.match(Filename); + return RegExp->match(Filename); +} + +/// Matches statements that are (transitively) expanded from the named macro. +/// 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) { + // Verifies that the statement' beginning and ending are both expanded from + // the same instance of the given macro. + auto& Context = Finder->getASTContext(); + llvm::Optional B = + internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context); + if (!B) return false; + llvm::Optional E = + internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context); + if (!E) return false; + return *B == *E; } /// Matches declarations. @@ -526,52 +549,72 @@ extern const internal::VariadicDynCastAllOfMatcher templateTypeParmDecl; -/// Matches public C++ declarations. +/// Matches public C++ declarations and C++ base specifers that specify public +/// inheritance. /// -/// Given +/// Examples: /// \code /// class C { -/// public: int a; +/// public: int a; // fieldDecl(isPublic()) matches 'a' /// protected: int b; /// private: int c; /// }; /// \endcode -/// fieldDecl(isPublic()) -/// matches 'int a;' -AST_MATCHER(Decl, isPublic) { - return Node.getAccess() == AS_public; +/// +/// \code +/// class Base {}; +/// class Derived1 : public Base {}; // matches 'Base' +/// struct Derived2 : Base {}; // matches 'Base' +/// \endcode +AST_POLYMORPHIC_MATCHER(isPublic, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, + CXXBaseSpecifier)) { + return getAccessSpecifier(Node) == AS_public; } -/// Matches protected C++ declarations. +/// Matches protected C++ declarations and C++ base specifers that specify +/// protected inheritance. /// -/// Given +/// Examples: /// \code /// class C { /// public: int a; -/// protected: int b; +/// protected: int b; // fieldDecl(isProtected()) matches 'b' /// private: int c; /// }; /// \endcode -/// fieldDecl(isProtected()) -/// matches 'int b;' -AST_MATCHER(Decl, isProtected) { - return Node.getAccess() == AS_protected; +/// +/// \code +/// class Base {}; +/// class Derived : protected Base {}; // matches 'Base' +/// \endcode +AST_POLYMORPHIC_MATCHER(isProtected, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, + CXXBaseSpecifier)) { + return getAccessSpecifier(Node) == AS_protected; } -/// Matches private C++ declarations. +/// Matches private C++ declarations and C++ base specifers that specify private +/// inheritance. /// -/// Given +/// Examples: /// \code /// class C { /// public: int a; /// protected: int b; -/// private: int c; +/// private: int c; // fieldDecl(isPrivate()) matches 'c' /// }; /// \endcode -/// fieldDecl(isPrivate()) -/// matches 'int c;' -AST_MATCHER(Decl, isPrivate) { - return Node.getAccess() == AS_private; +/// +/// \code +/// struct Base {}; +/// struct Derived1 : private Base {}; // matches 'Base' +/// class Derived2 : Base {}; // matches 'Base' +/// \endcode +AST_POLYMORPHIC_MATCHER(isPrivate, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, + CXXBaseSpecifier)) { + return getAccessSpecifier(Node) == AS_private; } /// Matches non-static data members that are bit-fields. @@ -701,13 +744,13 @@ AST_POLYMORPHIC_MATCHER_P( /// \endcode /// The matcher /// \code -/// traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses, +/// traverse(TK_IgnoreImplicitCastsAndParentheses, /// varDecl(hasInitializer(floatLiteral().bind("init"))) /// ) /// \endcode /// matches the variable declaration with "init" bound to the "3.0". template -internal::Matcher traverse(ast_type_traits::TraversalKind TK, +internal::Matcher traverse(TraversalKind TK, const internal::Matcher &InnerMatcher) { return internal::DynTypedMatcher::constructRestrictedWrapper( new internal::TraversalMatcher(TK, InnerMatcher), @@ -717,8 +760,7 @@ internal::Matcher traverse(ast_type_traits::TraversalKind TK, template internal::BindableMatcher -traverse(ast_type_traits::TraversalKind TK, - const internal::BindableMatcher &InnerMatcher) { +traverse(TraversalKind TK, const internal::BindableMatcher &InnerMatcher) { return internal::BindableMatcher( internal::DynTypedMatcher::constructRestrictedWrapper( new internal::TraversalMatcher(TK, InnerMatcher), @@ -728,7 +770,7 @@ traverse(ast_type_traits::TraversalKind TK, template internal::TraversalWrapper> -traverse(ast_type_traits::TraversalKind TK, +traverse(TraversalKind TK, const internal::VariadicOperatorMatcher &InnerMatcher) { return internal::TraversalWrapper>( TK, InnerMatcher); @@ -738,9 +780,8 @@ template