diff --git a/.arcconfig b/.arcconfig index 7540b46523a..048706ac96e 100644 --- a/.arcconfig +++ b/.arcconfig @@ -1,4 +1,4 @@ { "project_id" : "clang", - "conduit_uri" : "http://reviews.llvm.org/" + "conduit_uri" : "https://reviews.llvm.org/" } diff --git a/.clang-tidy b/.clang-tidy index 3186da43d43..d10f688e591 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1 +1,12 @@ -Checks: '-*,clang-diagnostic-*,llvm-*,misc-*' +Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming' +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: lowerCase + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: CamelCase diff --git a/.gitignore b/.gitignore index 3d07e81baf3..fc842489a03 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ tools/extra # Sphinx build products docs/_build docs/analyzer/_build +# debug info testsuite +test/debuginfo-tests diff --git a/CMakeLists.txt b/CMakeLists.txt index ad2ac42c403..cfcd2212cfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,4 @@ -cmake_minimum_required(VERSION 2.8.8) - -# FIXME: It may be removed when we use 2.8.12. -if(CMAKE_VERSION VERSION_LESS 2.8.12) - # Invalidate a couple of keywords. - set(cmake_2_8_12_INTERFACE) - set(cmake_2_8_12_PRIVATE) -else() - # Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries(). - set(cmake_2_8_12_INTERFACE INTERFACE) - set(cmake_2_8_12_PRIVATE PRIVATE) - if(POLICY CMP0022) - cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required - endif() -endif() +cmake_minimum_required(VERSION 3.4.3) # If we are not building as a part of LLVM, build Clang as an # standalone project, using LLVM as an external library: @@ -72,7 +58,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) - set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/share/llvm/cmake") + set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake") if(EXISTS ${LLVMCONFIG_FILE}) list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") @@ -101,6 +87,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) include(AddLLVM) include(TableGen) include(HandleLLVMOptions) + include(VersionFromVCS) set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}") @@ -181,6 +168,10 @@ else() set(BACKEND_PACKAGE_STRING "${PACKAGE_STRING}") endif() +# Make sure that our source directory is on the current cmake module path so that +# we can include cmake files from this directory. +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + find_package(LibXml2 2.5.3 QUIET) if (LIBXML2_FOUND) set(CLANG_HAVE_LIBXML 1) @@ -196,10 +187,24 @@ set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." ) set(DEFAULT_SYSROOT "" CACHE PATH "Default to all compiler invocations for --sysroot=." ) +set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld") + +set(ENABLE_X86_RELAX_RELOCATIONS OFF CACHE BOOL + "enable x86 relax relocations by default") + +set(CLANG_DEFAULT_CXX_STDLIB "" CACHE STRING + "Default C++ stdlib to use (empty for architecture default, \"libstdc++\" or \"libc++\"") +if (NOT(CLANG_DEFAULT_CXX_STDLIB STREQUAL "" OR + CLANG_DEFAULT_CXX_STDLIB STREQUAL "libstdc++" OR + CLANG_DEFAULT_CXX_STDLIB STREQUAL "libc++")) + message(WARNING "Resetting default C++ stdlib to use architecture default") + set(CLANG_DEFAULT_CXX_STDLIB "") +endif() + set(CLANG_DEFAULT_OPENMP_RUNTIME "libomp" CACHE STRING "Default OpenMP runtime used by -fopenmp.") -set(CLANG_VENDOR "" CACHE STRING +set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING "Vendor-specific text for showing with version information.") if( CLANG_VENDOR ) @@ -307,134 +312,7 @@ configure_file( ${CLANG_BINARY_DIR}/include/clang/Config/config.h) include(CMakeParseArguments) - -function(clang_tablegen) - # Syntax: - # clang_tablegen output-file [tablegen-arg ...] SOURCE source-file - # [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]] - # - # Generates a custom command for invoking tblgen as - # - # tblgen source-file -o=output-file tablegen-arg ... - # - # and, if cmake-target-name is provided, creates a custom target for - # executing the custom command depending on output-file. It is - # possible to list more files to depend after DEPENDS. - - cmake_parse_arguments(CTG "" "SOURCE;TARGET" "" ${ARGN}) - - if( NOT CTG_SOURCE ) - message(FATAL_ERROR "SOURCE source-file required by clang_tablegen") - endif() - - set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} ) - tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS}) - - if(CTG_TARGET) - add_public_tablegen_target(${CTG_TARGET}) - set_target_properties( ${CTG_TARGET} PROPERTIES FOLDER "Clang tablegenning") - set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET}) - endif() -endfunction(clang_tablegen) - -macro(set_clang_windows_version_resource_properties name) - if(DEFINED windows_resource_file) - set_windows_version_resource_properties(${name} ${windows_resource_file} - VERSION_MAJOR ${CLANG_VERSION_MAJOR} - VERSION_MINOR ${CLANG_VERSION_MINOR} - VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL} - VERSION_STRING "${CLANG_VERSION} (${BACKEND_PACKAGE_STRING})" - PRODUCT_NAME "clang") - endif() -endmacro() - -macro(add_clang_subdirectory name) - add_llvm_subdirectory(CLANG TOOL ${name}) -endmacro() - -macro(add_clang_library name) - cmake_parse_arguments(ARG - "SHARED" - "" - "ADDITIONAL_HEADERS" - ${ARGN}) - set(srcs) - if(MSVC_IDE OR XCODE) - # Add public headers - file(RELATIVE_PATH lib_path - ${CLANG_SOURCE_DIR}/lib/ - ${CMAKE_CURRENT_SOURCE_DIR} - ) - if(NOT lib_path MATCHES "^[.][.]") - file( GLOB_RECURSE headers - ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.h - ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.def - ) - set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON) - - file( GLOB_RECURSE tds - ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.td - ) - source_group("TableGen descriptions" FILES ${tds}) - set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON) - - if(headers OR tds) - set(srcs ${headers} ${tds}) - endif() - endif() - endif(MSVC_IDE OR XCODE) - if(srcs OR ARG_ADDITIONAL_HEADERS) - set(srcs - ADDITIONAL_HEADERS - ${srcs} - ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args. - ) - endif() - if(ARG_SHARED) - set(ARG_ENABLE_SHARED SHARED) - endif() - llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS} ${srcs}) - - if(TARGET ${name}) - target_link_libraries(${name} ${cmake_2_8_12_INTERFACE} ${LLVM_COMMON_LIBS}) - - if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang") - install(TARGETS ${name} - COMPONENT ${name} - EXPORT ClangTargets - LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} - RUNTIME DESTINATION bin) - - if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES) - add_custom_target(install-${name} - DEPENDS ${name} - COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=${name} - -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") - endif() - endif() - set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) - else() - # Add empty "phony" target - add_custom_target(${name}) - endif() - - set_target_properties(${name} PROPERTIES FOLDER "Clang libraries") - set_clang_windows_version_resource_properties(${name}) -endmacro(add_clang_library) - -macro(add_clang_executable name) - add_llvm_executable( ${name} ${ARGN} ) - set_target_properties(${name} PROPERTIES FOLDER "Clang executables") - set_clang_windows_version_resource_properties(${name}) -endmacro(add_clang_executable) - -macro(add_clang_symlink name dest) - add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE) - # Always generate install targets - llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE) -endmacro() +include(AddClang) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -462,30 +340,11 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) ) endif() -if(INTERNAL_INSTALL_PREFIX) - set(LIBCLANG_HEADERS_INSTALL_DESTINATION "${INTERNAL_INSTALL_PREFIX}/include") -else() - set(LIBCLANG_HEADERS_INSTALL_DESTINATION include) -endif() - -install(DIRECTORY include/clang-c - COMPONENT libclang-headers - DESTINATION "${LIBCLANG_HEADERS_INSTALL_DESTINATION}" - FILES_MATCHING - PATTERN "*.h" - PATTERN ".svn" EXCLUDE - ) - -if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's. - add_custom_target(install-libclang-headers - DEPENDS - COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=libclang-headers - -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") -endif() - add_definitions( -D_GNU_SOURCE ) +option(CLANG_BUILD_TOOLS + "Build the Clang tools. If OFF, just generate build targets." ON) + option(CLANG_ENABLE_ARCMT "Build ARCMT." ON) if (CLANG_ENABLE_ARCMT) set(ENABLE_CLANG_ARCMT "1") @@ -579,50 +438,33 @@ if( CLANG_INCLUDE_DOCS ) add_subdirectory(docs) endif() -set(CLANG_ORDER_FILE "" CACHE FILEPATH - "Order file to use when compiling clang in order to improve startup time.") - -if (CLANG_BUILT_STANDALONE OR CMAKE_VERSION VERSION_EQUAL 3 OR - CMAKE_VERSION VERSION_GREATER 3) - # Generate a list of CMake library targets so that other CMake projects can - # link against them. LLVM calls its version of this file LLVMExports.cmake, but - # the usual CMake convention seems to be ${Project}Targets.cmake. - set(CLANG_INSTALL_PACKAGE_DIR share/clang/cmake) - set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}") - get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS) - export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake) - - # Install a /share/clang/cmake/ClangConfig.cmake file so that - # find_package(Clang) works. Install the target list with it. - install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR}) - - install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake - DESTINATION share/clang/cmake) - - # Also copy ClangConfig.cmake to the build directory so that dependent projects - # can build against a build directory of Clang more easily. - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake - ${CLANG_BINARY_DIR}/share/clang/cmake/ClangConfig.cmake - COPYONLY) -endif () -if (CLANG_ENABLE_BOOTSTRAP) - include(ExternalProject) - - if(CMAKE_VERSION VERSION_GREATER 3.1.0) - set(cmake_3_1_EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL 1) +if(APPLE) + # this line is needed as a cleanup to ensure that any CMakeCaches with the old + # default value get updated to the new default. + if(CLANG_ORDER_FILE STREQUAL "") + unset(CLANG_ORDER_FILE CACHE) + unset(CLANG_ORDER_FILE) endif() - if(CMAKE_VERSION VERSION_GREATER 3.3.20150708) - set(cmake_3_4_USES_TERMINAL_OPTIONS - USES_TERMINAL_CONFIGURE 1 - USES_TERMINAL_BUILD 1 - USES_TERMINAL_INSTALL 1 - ) - set(cmake_3_4_USES_TERMINAL USES_TERMINAL 1) + + set(CLANG_ORDER_FILE ${CMAKE_CURRENT_BINARY_DIR}/clang.order CACHE FILEPATH + "Order file to use when compiling clang in order to improve startup time (Darwin Only - requires ld64).") + + if(CLANG_ORDER_FILE AND NOT EXISTS ${CLANG_ORDER_FILE}) + string(FIND "${CLANG_ORDER_FILE}" "${CMAKE_CURRENT_BINARY_DIR}" PATH_START) + if(PATH_START EQUAL 0) + file(WRITE ${CLANG_ORDER_FILE} "\n") + else() + message(FATAL_ERROR "Specified order file '${CLANG_ORDER_FILE}' does not exist.") + endif() endif() +endif() + +add_subdirectory(cmake/modules) + +if (CLANG_ENABLE_BOOTSTRAP) + include(ExternalProject) if(NOT CLANG_STAGE) set(CLANG_STAGE stage1) @@ -649,14 +491,22 @@ if (CLANG_ENABLE_BOOTSTRAP) set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-stamps/) set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-bins/) - - # If on Darwin we need to make bootstrap depend on LTO and pass - # DARWIN_LTO_LIBRARY so that -flto will work using the just-built compiler - if(APPLE) - set(LTO_DEP LTO llvm-ar llvm-ranlib) - set(LTO_LIBRARY -DDARWIN_LTO_LIBRARY=${LLVM_SHLIB_OUTPUT_INTDIR}/libLTO.dylib) - set(LTO_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar) - set(LTO_RANLIB -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib) + set(cmake_command ${CMAKE_COMMAND}) + + # If the next stage is LTO we need to depend on LTO and possibly LLVMgold + if(BOOTSTRAP_LLVM_ENABLE_LTO OR LLVM_ENABLE_LTO) + set(LTO_DEP LTO) + if(APPLE) + # on Darwin we need to set DARWIN_LTO_LIBRARY so that -flto will work + # using the just-built compiler, and we need to override DYLD_LIBRARY_PATH + # so that the host object file tools will use the just-built libLTO. + set(LTO_LIBRARY -DDARWIN_LTO_LIBRARY=${LLVM_SHLIB_OUTPUT_INTDIR}/libLTO.dylib) + set(cmake_command ${CMAKE_COMMAND} -E env DYLD_LIBRARY_PATH=${LLVM_LIBRARY_OUTPUT_INTDIR} ${CMAKE_COMMAND}) + elseif(NOT WIN32) + list(APPEND LTO_DEP LLVMgold llvm-ar llvm-ranlib) + set(LTO_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar) + set(LTO_RANLIB -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib) + endif() endif() add_custom_target(${NEXT_CLANG_STAGE}-clear @@ -682,6 +532,7 @@ if (CLANG_ENABLE_BOOTSTRAP) LLVM_VERSION_MINOR LLVM_VERSION_PATCH LLVM_VERSION_SUFFIX + LLVM_BINUTILS_INCDIR CLANG_REPOSITORY_STRING CMAKE_MAKE_PROGRAM) @@ -719,6 +570,10 @@ if (CLANG_ENABLE_BOOTSTRAP) list(APPEND PASSTHROUGH_VARIABLES -D${varName}=${value}) endif() + if(${variableName} AND variableName MATCHES "LLVM_EXTERNAL_.*_SOURCE_DIR") + list(APPEND PASSTHROUGH_VARIABLES + -D${variableName}=${${variableName}}) + endif() endforeach() # Populate the passthrough variables @@ -736,7 +591,7 @@ if (CLANG_ENABLE_BOOTSTRAP) SOURCE_DIR ${CMAKE_SOURCE_DIR} STAMP_DIR ${STAMP_DIR} BINARY_DIR ${BINARY_DIR} - ${cmake_3_1_EXCLUDE_FROM_ALL} + EXCLUDE_FROM_ALL 1 CMAKE_ARGS # We shouldn't need to set this here, but INSTALL_DIR doesn't # seem to work, so instead I'm passing this through @@ -746,18 +601,21 @@ if (CLANG_ENABLE_BOOTSTRAP) -DCLANG_STAGE=${NEXT_CLANG_STAGE} ${COMPILER_OPTIONS} ${LTO_LIBRARY} ${LTO_AR} ${LTO_RANLIB} ${verbose} ${PGO_OPT} + CMAKE_COMMAND ${cmake_command} INSTALL_COMMAND "" STEP_TARGETS configure build - ${cmake_3_4_USES_TERMINAL_OPTIONS} + USES_TERMINAL_CONFIGURE 1 + USES_TERMINAL_BUILD 1 + USES_TERMINAL_INSTALL 1 ) # exclude really-install from main target set_target_properties(${NEXT_CLANG_STAGE} PROPERTIES _EP_really-install_EXCLUDE_FROM_MAIN On) ExternalProject_Add_Step(${NEXT_CLANG_STAGE} really-install - COMMAND ${CMAKE_COMMAND} --build --target install + COMMAND ${cmake_command} --build --target install COMMENT "Performing install step for '${NEXT_CLANG_STAGE}'" DEPENDEES build - ${cmake_3_4_USES_TERMINAL} + USES_TERMINAL 1 ) ExternalProject_Add_StepTargets(${NEXT_CLANG_STAGE} really-install) add_custom_target(${NEXT_CLANG_STAGE}-install DEPENDS ${NEXT_CLANG_STAGE}-really-install) @@ -770,10 +628,10 @@ if (CLANG_ENABLE_BOOTSTRAP) set_target_properties(${NEXT_CLANG_STAGE} PROPERTIES _EP_${target}_EXCLUDE_FROM_MAIN On) ExternalProject_Add_Step(${NEXT_CLANG_STAGE} ${target} - COMMAND ${CMAKE_COMMAND} --build --target ${target} + COMMAND ${cmake_command} --build --target ${target} COMMENT "Performing ${target} for '${NEXT_CLANG_STAGE}'" DEPENDEES configure - ${cmake_3_4_USES_TERMINAL} + USES_TERMINAL 1 ) if(target MATCHES "^stage[0-9]*") @@ -783,3 +641,7 @@ if (CLANG_ENABLE_BOOTSTRAP) ExternalProject_Add_StepTargets(${NEXT_CLANG_STAGE} ${target}) endforeach() endif() + +if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) + add_subdirectory(utils/ClangVisualizers) +endif() diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index 971fe9bde10..0aa156b858e 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -23,7 +23,7 @@ D: CMake, library layering N: Eric Christopher E: echristo@gmail.com -D: Debug Information, autotools/configure/make build, inline assembly +D: Debug Information, inline assembly N: Doug Gregor E: dgregor@apple.com @@ -52,3 +52,7 @@ D: Clang LLVM IR generation N: Richard Smith E: richard@metafoo.co.uk D: All parts of Clang not covered by someone else + +N: Anastasia Stulova +E: anastasia.stulova@arm.com +D: OpenCL support diff --git a/LICENSE.TXT b/LICENSE.TXT index fc4afae584b..b452ca2efd8 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -4,7 +4,7 @@ LLVM Release License University of Illinois/NCSA Open Source License -Copyright (c) 2007-2015 University of Illinois at Urbana-Champaign. +Copyright (c) 2007-2016 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: diff --git a/Makefile b/Makefile deleted file mode 100644 index 9497b0a4219..00000000000 --- a/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -##===- Makefile --------------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -# If CLANG_LEVEL is not set, then we are the top-level Makefile. Otherwise, we -# are being included from a subdirectory makefile. - -ifndef CLANG_LEVEL - -IS_TOP_LEVEL := 1 -CLANG_LEVEL := . -DIRS := utils/TableGen include lib tools runtime docs unittests - -PARALLEL_DIRS := - -ifeq ($(BUILD_EXAMPLES),1) - PARALLEL_DIRS += examples -endif -endif - -ifeq ($(BUILD_EXAMPLES),1) - ENABLE_CLANG_EXAMPLES := 1 -else - ENABLE_CLANG_EXAMPLES := 0 -endif - -ifeq ($(MAKECMDGOALS),libs-only) - DIRS := $(filter-out tools docs, $(DIRS)) - OPTIONAL_DIRS := -endif -ifeq ($(BUILD_CLANG_ONLY),YES) - DIRS := $(filter-out docs unittests, $(DIRS)) - OPTIONAL_DIRS := -endif - -### -# Common Makefile code, shared by all Clang Makefiles. - -# Set LLVM source root level. -LEVEL := $(CLANG_LEVEL)/../.. - -# Include LLVM common makefile. -include $(LEVEL)/Makefile.common - -ifneq ($(ENABLE_DOCS),1) - DIRS := $(filter-out docs, $(DIRS)) -endif - -# Set common Clang build flags. -CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include -I$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include -ifdef CLANG_VENDOR -CPP.Flags += -DCLANG_VENDOR='"$(CLANG_VENDOR) "' -endif -ifdef CLANG_REPOSITORY_STRING -CPP.Flags += -DCLANG_REPOSITORY_STRING='"$(CLANG_REPOSITORY_STRING)"' -endif - -# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't -# work with it enabled with GCC), Clang/llvm-gcc don't support it yet, and newer -# GCC's have false positive warnings with it on Linux (which prove a pain to -# fix). For example: -# http://gcc.gnu.org/PR41874 -# http://gcc.gnu.org/PR41838 -# -# We don't need to do this if the host compiler is clang. -ifneq ($(CXX_COMPILER), "clang") -CXX.Flags += -fno-strict-aliasing -endif - - -# Set up Clang's tblgen. -ifndef CLANG_TBLGEN - ifeq ($(LLVM_CROSS_COMPILING),1) - CLANG_TBLGEN := $(BuildLLVMToolDir)/clang-tblgen$(BUILD_EXEEXT) - else - CLANG_TBLGEN := $(LLVMToolDir)/clang-tblgen$(EXEEXT) - endif -endif -ClangTableGen = $(CLANG_TBLGEN) $(TableGen.Flags) - -### -# Clang Top Level specific stuff. - -ifeq ($(IS_TOP_LEVEL),1) - -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) -$(RecursiveTargets):: - $(Verb) for dir in test unittests; do \ - if [ -f $(PROJ_SRC_DIR)/$${dir}/Makefile ] && [ ! -f $${dir}/Makefile ]; then \ - $(MKDIR) $${dir}; \ - $(CP) $(PROJ_SRC_DIR)/$${dir}/Makefile $${dir}/Makefile; \ - fi \ - done -endif - -test:: - @ $(MAKE) -C test - -report:: - @ $(MAKE) -C test report - -clean:: - @ $(MAKE) -C test clean - -libs-only: all - -tags:: - $(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \ - grep -v /lib/Headers | grep -v /test/` - -cscope.files: - find tools lib include -name '*.cpp' \ - -or -name '*.def' \ - -or -name '*.td' \ - -or -name '*.h' > cscope.files - -.PHONY: test report clean cscope.files - -endif diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index e4b38769b77..aeb34f8cb23 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -359,6 +359,23 @@ def __getitem__(self, key): return FixItIterator(self) + @property + def children(self): + class ChildDiagnosticsIterator: + def __init__(self, diag): + self.diag_set = conf.lib.clang_getChildDiagnostics(diag) + + def __len__(self): + return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set)) + + def __getitem__(self, key): + diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key) + if not diag: + raise IndexError + return Diagnostic(diag) + + return ChildDiagnosticsIterator(self) + @property def category_number(self): """The category number for this diagnostic or 0 if unavailable.""" @@ -1120,6 +1137,9 @@ def __repr__(self): # A type alias template declaration CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601) +# A code completion overload candidate. +CursorKind.OVERLOAD_CANDIDATE = CursorKind(700) + ### Template Argument Kinds ### class TemplateArgumentKind(BaseEnumeration): """ @@ -1174,6 +1194,32 @@ def is_const_method(self): """ return conf.lib.clang_CXXMethod_isConst(self) + def is_converting_constructor(self): + """Returns True if the cursor refers to a C++ converting constructor. + """ + return conf.lib.clang_CXXConstructor_isConvertingConstructor(self) + + def is_copy_constructor(self): + """Returns True if the cursor refers to a C++ copy constructor. + """ + return conf.lib.clang_CXXConstructor_isCopyConstructor(self) + + def is_default_constructor(self): + """Returns True if the cursor refers to a C++ default constructor. + """ + return conf.lib.clang_CXXConstructor_isDefaultConstructor(self) + + def is_move_constructor(self): + """Returns True if the cursor refers to a C++ move constructor. + """ + return conf.lib.clang_CXXConstructor_isMoveConstructor(self) + + def is_default_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared '= default'. + """ + return conf.lib.clang_CXXMethod_isDefaulted(self) + def is_mutable_field(self): """Returns True if the cursor refers to a C++ field that is declared 'mutable'. @@ -1685,6 +1731,7 @@ def __repr__(self): TypeKind.OBJCID = TypeKind(27) TypeKind.OBJCCLASS = TypeKind(28) TypeKind.OBJCSEL = TypeKind(29) +TypeKind.FLOAT128 = TypeKind(30) TypeKind.COMPLEX = TypeKind(100) TypeKind.POINTER = TypeKind(101) TypeKind.BLOCKPOINTER = TypeKind(102) @@ -1704,6 +1751,7 @@ def __repr__(self): TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116) TypeKind.MEMBERPOINTER = TypeKind(117) TypeKind.AUTO = TypeKind(118) +TypeKind.ELABORATED = TypeKind(119) class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" @@ -1902,6 +1950,12 @@ def get_class_type(self): """ return conf.lib.clang_Type_getClassType(self) + def get_named_type(self): + """ + Retrieve the type named by the qualified-id. + """ + return conf.lib.clang_Type_getNamedType(self) + def get_align(self): """ Retrieve the alignment of the record. @@ -2383,7 +2437,7 @@ def __init__(self, ptr, index): functions above. __init__ is only called internally. """ assert isinstance(index, Index) - + self.index = index ClangObject.__init__(self, ptr) def __del__(self): @@ -2702,6 +2756,11 @@ def directory(self): """Get the working directory for this CompileCommand""" return conf.lib.clang_CompileCommand_getDirectory(self.cmd) + @property + def filename(self): + """Get the working filename for this CompileCommand""" + return conf.lib.clang_CompileCommand_getFilename(self.cmd) + @property def arguments(self): """ @@ -2884,6 +2943,11 @@ def cursor(self): _CXString, _CXString.from_result), + ("clang_CompileCommand_getFilename", + [c_object_p], + _CXString, + _CXString.from_result), + ("clang_CompileCommand_getNumArgs", [c_object_p], c_uint), @@ -2908,6 +2972,22 @@ def cursor(self): [Index, c_char_p], c_object_p), + ("clang_CXXConstructor_isConvertingConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isCopyConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isDefaultConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isMoveConstructor", + [Cursor], + bool), + ("clang_CXXField_isMutable", [Cursor], bool), @@ -2916,6 +2996,10 @@ def cursor(self): [Cursor], bool), + ("clang_CXXMethod_isDefaulted", + [Cursor], + bool), + ("clang_CXXMethod_isPureVirtual", [Cursor], bool), @@ -2997,6 +3081,10 @@ def cursor(self): Type, Type.from_result), + ("clang_getChildDiagnostics", + [Diagnostic], + c_object_p), + ("clang_getCompletionAvailability", [c_void_p], c_int), @@ -3117,6 +3205,10 @@ def cursor(self): _CXString, _CXString.from_result), + ("clang_getDiagnosticInSet", + [c_object_p, c_uint], + c_object_p), + ("clang_getDiagnosticLocation", [Diagnostic], SourceLocation), @@ -3218,6 +3310,10 @@ def cursor(self): [c_object_p], c_uint), + ("clang_getNumDiagnosticsInSet", + [c_object_p], + c_uint), + ("clang_getNumElements", [Type], c_longlong), @@ -3477,6 +3573,11 @@ def cursor(self): [Type], c_uint), + ("clang_Type_getNamedType", + [Type], + Type, + Type.from_result), + ("clang_Type_visitFields", [Type, callbacks['fields_visit'], py_object], c_uint), diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py index e1f824f797f..35fe3e108a1 100644 --- a/bindings/python/tests/cindex/test_cdb.py +++ b/bindings/python/tests/cindex/test_cdb.py @@ -38,27 +38,34 @@ def test_all_compilecommand(): cmds = cdb.getAllCompileCommands() assert len(cmds) == 3 expected = [ + { 'wd': '/home/john.doe/MyProject', + 'file': '/home/john.doe/MyProject/project.cpp', + 'line': ['clang++', '-o', 'project.o', '-c', + '/home/john.doe/MyProject/project.cpp']}, { 'wd': '/home/john.doe/MyProjectA', + 'file': '/home/john.doe/MyProject/project2.cpp', 'line': ['clang++', '-o', 'project2.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, { 'wd': '/home/john.doe/MyProjectB', + 'file': '/home/john.doe/MyProject/project2.cpp', 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, - { 'wd': '/home/john.doe/MyProject', - 'line': ['clang++', '-o', 'project.o', '-c', - '/home/john.doe/MyProject/project.cpp']} + ] for i in range(len(cmds)): assert cmds[i].directory == expected[i]['wd'] + assert cmds[i].filename == expected[i]['file'] for arg, exp in zip(cmds[i].arguments, expected[i]['line']): assert arg == exp def test_1_compilecommand(): """Check file with single compile command""" cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') + file = '/home/john.doe/MyProject/project.cpp' + cmds = cdb.getCompileCommands(file) assert len(cmds) == 1 - assert cmds[0].directory == '/home/john.doe/MyProject' + assert cmds[0].directory == os.path.dirname(file) + assert cmds[0].filename == file expected = [ 'clang++', '-o', 'project.o', '-c', '/home/john.doe/MyProject/project.cpp'] for arg, exp in zip(cmds[0].arguments, expected): diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index c5ea50516ad..6c8230d4283 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -112,6 +112,88 @@ def test_is_const_method(): assert foo.is_const_method() assert not bar.is_const_method() +def test_is_converting_constructor(): + """Ensure Cursor.is_converting_constructor works.""" + source = 'class X { explicit X(int); X(double); X(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + + assert len(xs) == 4 + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_converting_constructor() + assert cs[1].is_converting_constructor() + assert not cs[2].is_converting_constructor() + + +def test_is_copy_constructor(): + """Ensure Cursor.is_copy_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_copy_constructor() + assert cs[1].is_copy_constructor() + assert not cs[2].is_copy_constructor() + +def test_is_default_constructor(): + """Ensure Cursor.is_default_constructor works.""" + source = 'class X { X(); X(int); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + + assert cs[0].is_default_constructor() + assert not cs[1].is_default_constructor() + +def test_is_move_constructor(): + """Ensure Cursor.is_move_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_move_constructor() + assert not cs[1].is_move_constructor() + assert cs[2].is_move_constructor() + +def test_is_default_method(): + """Ensure Cursor.is_default_method works.""" + source = 'class X { X() = default; }; class Y { Y(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + ys = get_cursors(tu, 'Y') + + assert len(xs) == 2 + assert len(ys) == 2 + + xc = xs[1] + yc = ys[1] + + assert xc.is_default_method() + assert not yc.is_default_method() + def test_is_mutable_field(): """Ensure Cursor.is_mutable_field works.""" source = 'class X { int x_; mutable int y_; };' diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py index 48ab6176fd1..ba6e545e8b1 100644 --- a/bindings/python/tests/cindex/test_diagnostics.py +++ b/bindings/python/tests/cindex/test_diagnostics.py @@ -80,3 +80,15 @@ def test_diagnostic_option(): assert d.option == '-Wunused-parameter' assert d.disable_option == '-Wno-unused-parameter' + +def test_diagnostic_children(): + tu = get_tu('void f(int x) {} void g() { f(); }') + assert len(tu.diagnostics) == 1 + d = tu.diagnostics[0] + + children = d.children + assert len(children) == 1 + assert children[0].severity == Diagnostic.Note + assert children[0].spelling.endswith('declared here') + assert children[0].location.line == 1 + assert children[0].location.column == 1 diff --git a/cmake/caches/3-stage-base.cmake b/cmake/caches/3-stage-base.cmake new file mode 100644 index 00000000000..46c747edd77 --- /dev/null +++ b/cmake/caches/3-stage-base.cmake @@ -0,0 +1,15 @@ +set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "") +set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") +set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "") +set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") + +set(CLANG_BOOTSTRAP_TARGETS + clang + check-all + check-llvm + check-clang + test-suite CACHE STRING "") + +set(CLANG_BOOTSTRAP_CMAKE_ARGS + -C ${CMAKE_CURRENT_LIST_DIR}/3-stage-base.cmake + CACHE STRING "") diff --git a/cmake/caches/3-stage.cmake b/cmake/caches/3-stage.cmake new file mode 100644 index 00000000000..49bce39dfc9 --- /dev/null +++ b/cmake/caches/3-stage.cmake @@ -0,0 +1,16 @@ +set(CLANG_BOOTSTRAP_TARGETS + clang + check-all + check-llvm + check-clang + test-suite + stage3 + stage3-clang + stage3-check-all + stage3-check-llvm + stage3-check-clang + stage3-test-suite CACHE STRING "") + +set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "") + +include(${CMAKE_CURRENT_LIST_DIR}/3-stage-base.cmake) diff --git a/cmake/caches/Apple-stage1.cmake b/cmake/caches/Apple-stage1.cmake index a5c3fdbbdfd..814cfdf4860 100644 --- a/cmake/caches/Apple-stage1.cmake +++ b/cmake/caches/Apple-stage1.cmake @@ -16,15 +16,36 @@ set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "") set(COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "") set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") +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_BOOTSTRAP_PASSTHROUGH + CMAKE_OSX_ARCHITECTURES + CACHE STRING "") +set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") -set(PACKAGE_VERSION 7.1.0 CACHE STRING "") # LIBCXX Settings set(LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "") set(LIBCXX_INSTALL_HEADERS ON CACHE BOOL "") set(LIBCXX_OVERRIDE_DARWIN_INSTALL ON CACHE BOOL "") +set(CLANG_BOOTSTRAP_TARGETS + generate-order-file + check-all + check-llvm + check-clang + llvm-config + test-suite + test-depends + llvm-test-depends + clang-test-depends + distribution + install-distribution + clang CACHE STRING "") + #bootstrap set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") set(CLANG_BOOTSTRAP_CMAKE_ARGS diff --git a/cmake/caches/Apple-stage2.cmake b/cmake/caches/Apple-stage2.cmake index bb319aaeb86..9076868fd6d 100644 --- a/cmake/caches/Apple-stage2.cmake +++ b/cmake/caches/Apple-stage2.cmake @@ -2,23 +2,37 @@ # specified by the stage1 build. set(LLVM_TARGETS_TO_BUILD X86 ARM AArch64 CACHE STRING "") -set(CLANG_VENDOR Apple CACHE STRING "") -set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "") +set(PACKAGE_VENDOR Apple CACHE STRING "") set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") -set(LLVM_INCLUDE_UTILS OFF CACHE BOOL "") set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") -set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "") -set(COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "") -set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") +set(LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD OFF CACHE BOOL "") +set(CLANG_TOOL_SCAN_BUILD_BUILD OFF CACHE BOOL "") +set(CLANG_TOOL_SCAN_VIEW_BUILD OFF CACHE BOOL "") set(CLANG_LINKS_TO_CREATE clang++ cc c++ CACHE STRING "") +set(CMAKE_MACOSX_RPATH ON CACHE BOOL "") +set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") +set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") +set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "") +set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") +set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -flto -gline-tables-only -DNDEBUG" CACHE STRING "") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -flto -gline-tables-only -DNDEBUG" CACHE STRING "") +set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "Build Compiler-RT with just-built clang") +set(COMPILER_RT_ENABLE_IOS ON CACHE BOOL "Build iOS Compiler-RT libraries") + +# Make unit tests (if present) part of the ALL target +set(LLVM_BUILD_TESTS ON CACHE BOOL "") + +set(LLVM_ENABLE_LTO ON CACHE BOOL "") +set(CMAKE_C_FLAGS "-fno-stack-protector -fno-common -Wno-profile-instr-unprofiled" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-fno-stack-protector -fno-common -Wno-profile-instr-unprofiled" CACHE STRING "") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") -set(PACKAGE_VERSION 7.1.0 CACHE STRING "") set(LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "") -set(LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "") +set(LIBCXX_INSTALL_HEADERS ON CACHE BOOL "") +set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "") +set(LLVM_LTO_VERSION_OFFSET 3000 CACHE STRING "") # setup toolchain set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "") @@ -27,4 +41,20 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-cov llvm-dwarfdump llvm-profdata + llvm-objdump + llvm-nm + llvm-size + CACHE STRING "") + +set(LLVM_DISTRIBUTION_COMPONENTS + clang + LTO + clang-format + clang-headers + libcxx-headers + ${LLVM_TOOLCHAIN_TOOLS} CACHE STRING "") + +# test args + +set(LLVM_LIT_ARGS "--xunit-xml-output=testresults.xunit.xml -v" CACHE STRING "") diff --git a/cmake/caches/README.txt b/cmake/caches/README.txt index 55e5e159db1..db5c85a68fa 100644 --- a/cmake/caches/README.txt +++ b/cmake/caches/README.txt @@ -4,15 +4,71 @@ CMake Caches This directory contains CMake cache scripts that pre-populate the CMakeCache in a build directory with commonly used settings. -The first two cache files in the directory are used by Apple to build the clang -distribution packaged with Xcode. You can use the caches with the following -CMake invocation: +You can use the caches files with the following CMake invocation: cmake -G - -C /tools/clang/cmake/caches/Apple-stage1.cmake - -DCMAKE_BUILD_TYPE=Release - [-DCMAKE_INSTALL_PREFIX=] + -C + [additional CMake options (i.e. -DCMAKE_INSTALL_PREFIX=)] -Building the `bootstrap` target from this generation will build clang, and -`bootstrap-install` will install it. +Options specified on the command line will override options in the cache files. + +The following cache files exist. + +Apple-stage1 +------------ + +The Apple stage1 cache configures a two stage build similar to how Apple builds +the clang shipped with Xcode. The build files generated from this invocation has +a target named "stage2" which performs an LTO build of clang. + +The Apple-stage2 cache can be used directly to match the build settings Apple +uses in shipping builds without doing a full bootstrap build. + +PGO +--- + +The PGO CMake cache can be used to generate a multi-stage instrumented compiler. +You can configure your build directory with the following invocation of CMake: + +cmake -G -C /cmake/caches/PGO.cmake + +After configuration the following additional targets will be generated: + +stage2-instrumented: +Builds a stage1 x86 compiler, runtime, and required tools (llvm-config, +llvm-profdata) then uses that compiler to build an instrumented stage2 compiler. + +stage2-instrumented-generate-profdata: +Depends on "stage2-instrumented" and will use the instrumented compiler to +generate profdata based on the training files in /utils/perf-training + +stage2: +Depends on "stage2-instrumented-generate-profdata" and will use the stage1 +compiler with the stage2 profdata to build a PGO-optimized compiler. + +stage2-check-llvm: +Depends on stage2 and runs check-llvm using the stage3 compiler. + +stage2-check-clang: +Depends on stage2 and runs check-clang using the stage3 compiler. + +stage2-check-all: +Depends on stage2 and runs check-all using the stage3 compiler. + +stage2-test-suite: +Depends on stage2 and runs the test-suite using the stage3 compiler (requires +in-tree test-suite). + +3-stage +------- + +This cache file can be used to generate a 3-stage clang build. You can configure +using the following CMake command: + +cmake -C /cmake/caches/3-stage.cmake -G Ninja + +You can then run "ninja stage3-clang" to build stage1, stage2 and stage3 clangs. + +This is useful for finding non-determinism the compiler by verifying that stage2 +and stage3 are identical. diff --git a/cmake/modules/AddClang.cmake b/cmake/modules/AddClang.cmake new file mode 100644 index 00000000000..6e063a706bf --- /dev/null +++ b/cmake/modules/AddClang.cmake @@ -0,0 +1,149 @@ +function(clang_tablegen) + # Syntax: + # clang_tablegen output-file [tablegen-arg ...] SOURCE source-file + # [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]] + # + # Generates a custom command for invoking tblgen as + # + # tblgen source-file -o=output-file tablegen-arg ... + # + # and, if cmake-target-name is provided, creates a custom target for + # executing the custom command depending on output-file. It is + # possible to list more files to depend after DEPENDS. + + cmake_parse_arguments(CTG "" "SOURCE;TARGET" "" ${ARGN}) + + if( NOT CTG_SOURCE ) + message(FATAL_ERROR "SOURCE source-file required by clang_tablegen") + endif() + + set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} ) + tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS}) + + if(CTG_TARGET) + add_public_tablegen_target(${CTG_TARGET}) + set_target_properties( ${CTG_TARGET} PROPERTIES FOLDER "Clang tablegenning") + set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET}) + endif() +endfunction(clang_tablegen) + +macro(set_clang_windows_version_resource_properties name) + if(DEFINED windows_resource_file) + set_windows_version_resource_properties(${name} ${windows_resource_file} + VERSION_MAJOR ${CLANG_VERSION_MAJOR} + VERSION_MINOR ${CLANG_VERSION_MINOR} + VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL} + VERSION_STRING "${CLANG_VERSION} (${BACKEND_PACKAGE_STRING})" + PRODUCT_NAME "clang") + endif() +endmacro() + +macro(add_clang_subdirectory name) + add_llvm_subdirectory(CLANG TOOL ${name}) +endmacro() + +macro(add_clang_library name) + cmake_parse_arguments(ARG + "SHARED" + "" + "ADDITIONAL_HEADERS" + ${ARGN}) + set(srcs) + if(MSVC_IDE OR XCODE) + # Add public headers + file(RELATIVE_PATH lib_path + ${CLANG_SOURCE_DIR}/lib/ + ${CMAKE_CURRENT_SOURCE_DIR} + ) + if(NOT lib_path MATCHES "^[.][.]") + file( GLOB_RECURSE headers + ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.h + ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.def + ) + set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON) + + file( GLOB_RECURSE tds + ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.td + ) + source_group("TableGen descriptions" FILES ${tds}) + set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON) + + if(headers OR tds) + set(srcs ${headers} ${tds}) + endif() + endif() + endif(MSVC_IDE OR XCODE) + if(srcs OR ARG_ADDITIONAL_HEADERS) + set(srcs + ADDITIONAL_HEADERS + ${srcs} + ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args. + ) + endif() + if(ARG_SHARED) + set(ARG_ENABLE_SHARED SHARED) + endif() + llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS} ${srcs}) + + if(TARGET ${name}) + target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS}) + + if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang") + install(TARGETS ${name} + COMPONENT ${name} + EXPORT ClangTargets + LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} + RUNTIME DESTINATION bin) + + if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES) + add_custom_target(install-${name} + DEPENDS ${name} + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT=${name} + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + endif() + endif() + set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) + else() + # Add empty "phony" target + add_custom_target(${name}) + endif() + + set_target_properties(${name} PROPERTIES FOLDER "Clang libraries") + set_clang_windows_version_resource_properties(${name}) +endmacro(add_clang_library) + +macro(add_clang_executable name) + add_llvm_executable( ${name} ${ARGN} ) + set_target_properties(${name} PROPERTIES FOLDER "Clang executables") + set_clang_windows_version_resource_properties(${name}) +endmacro(add_clang_executable) + +macro(add_clang_tool name) + if (NOT CLANG_BUILD_TOOLS) + set(EXCLUDE_FROM_ALL ON) + endif() + + add_clang_executable(${name} ${ARGN}) + + if (CLANG_BUILD_TOOLS) + install(TARGETS ${name} + RUNTIME DESTINATION bin + COMPONENT ${name}) + + if(NOT CMAKE_CONFIGURATION_TYPES) + add_custom_target(install-${name} + DEPENDS ${name} + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT=${name} + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + endif() + endif() +endmacro() + +macro(add_clang_symlink name dest) + add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE) + # Always generate install targets + llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE) +endmacro() diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt new file mode 100644 index 00000000000..3cc808a46b9 --- /dev/null +++ b/cmake/modules/CMakeLists.txt @@ -0,0 +1,47 @@ +# Generate a list of CMake library targets so that other CMake projects can +# link against them. LLVM calls its version of this file LLVMExports.cmake, but +# the usual CMake convention seems to be ${Project}Targets.cmake. +set(CLANG_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/clang) +set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}") + +get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS) +export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake) + +# Generate ClangConfig.cmake for the build tree. +set(CLANG_CONFIG_CMAKE_DIR "${clang_cmake_builddir}") +set(CLANG_CONFIG_EXPORTS_FILE "${clang_cmake_builddir}/ClangTargets.cmake") +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in + ${clang_cmake_builddir}/ClangConfig.cmake + @ONLY) +set(CLANG_CONFIG_CMAKE_DIR) +set(CLANG_CONFIG_EXPORTS_FILE) + +# Generate ClangConfig.cmake for the install tree. +set(CLANG_CONFIG_CODE " +# Compute the installation prefix from this LLVMConfig.cmake file location. +get_filename_component(CLANG_INSTALL_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)") +# Construct the proper number of get_filename_component(... PATH) +# calls to compute the installation prefix. +string(REGEX REPLACE "/" ";" _count "${CLANG_INSTALL_PACKAGE_DIR}") +foreach(p ${_count}) + set(CLANG_CONFIG_CODE "${CLANG_CONFIG_CODE} +get_filename_component(CLANG_INSTALL_PREFIX \"\${CLANG_INSTALL_PREFIX}\" PATH)") +endforeach(p) +set(CLANG_CONFIG_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${CLANG_INSTALL_PACKAGE_DIR}") +set(CLANG_CONFIG_EXPORTS_FILE "\${CLANG_CMAKE_DIR}/ClangTargets.cmake") +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake + @ONLY) +set(CLANG_CONFIG_CODE) +set(CLANG_CONFIG_CMAKE_DIR) +set(CLANG_CONFIG_EXPORTS_FILE) + +if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) + install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR}) + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake + DESTINATION ${CLANG_INSTALL_PACKAGE_DIR}) +endif() diff --git a/cmake/modules/ClangConfig.cmake b/cmake/modules/ClangConfig.cmake deleted file mode 100644 index f052bb9e8c8..00000000000 --- a/cmake/modules/ClangConfig.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# This file allows users to call find_package(Clang) and pick up our targets. - -# Clang doesn't have any CMake configuration settings yet because it mostly -# uses LLVM's. When it does, we should move this file to ClangConfig.cmake.in -# and call configure_file() on it. - -# Provide all our library targets to users. -include("${CMAKE_CURRENT_LIST_DIR}/ClangTargets.cmake") diff --git a/cmake/modules/ClangConfig.cmake.in b/cmake/modules/ClangConfig.cmake.in new file mode 100644 index 00000000000..a946944dd99 --- /dev/null +++ b/cmake/modules/ClangConfig.cmake.in @@ -0,0 +1,11 @@ +# This file allows users to call find_package(Clang) and pick up our targets. + +find_package(LLVM REQUIRED CONFIG) + +@CLANG_CONFIG_CODE@ + +set(CLANG_EXPORTED_TARGETS "@CLANG_EXPORTS@") +set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@") + +# Provide all our library targets to users. +include("@CLANG_CONFIG_EXPORTS_FILE@") diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst index 93f63143210..a42a1ff6237 100644 --- a/docs/AddressSanitizer.rst +++ b/docs/AddressSanitizer.rst @@ -232,6 +232,23 @@ problems happening in certain source files or with certain global variables. type:*BadInitClassSubstring*=init src:bad/init/files/*=init +Suppressing memory leaks +------------------------ + +Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part +of AddressSanitizer) can be suppressed by a separate file passed as + +.. code-block:: bash + + LSAN_OPTIONS=suppressions=MyLSan.supp + +which contains lines of the form `leak:`. Memory leak will be +suppressed if pattern matches any function name, source file name, or +library name in the symbolized stack trace of the leak report. See +`full documentation +`_ +for more details. + Limitations =========== diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst index a763ddeaeb1..054d706fb28 100644 --- a/docs/AttributeReference.rst +++ b/docs/AttributeReference.rst @@ -1,13 +1,2736 @@ .. ------------------------------------------------------------------- NOTE: This file is automatically generated by running clang-tblgen - -gen-attr-docs. Do not edit this file by hand!! The contents for - this file are automatically generated by a server-side process. - - Please do not commit this file. The file exists for local testing - purposes only. + -gen-attr-docs. Do not edit this file by hand!! ------------------------------------------------------------------- =================== Attributes in Clang -=================== \ No newline at end of file +=================== +.. contents:: + :local: + +Introduction +============ + +This page lists the attributes currently supported by Clang. + +Function Attributes +=================== + + +interrupt +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on +ARM targets. This attribute may be attached to a function definition and +instructs the backend to generate appropriate function entry/exit code so that +it can be used directly as an interrupt service routine. + +The parameter passed to the interrupt attribute is optional, but if +provided it must be a string literal with one of the following values: "IRQ", +"FIQ", "SWI", "ABORT", "UNDEF". + +The semantics are as follows: + +- If the function is AAPCS, Clang instructs the backend to realign the stack to + 8 bytes on entry. This is a general requirement of the AAPCS at public + interfaces, but may not hold when an exception is taken. Doing this allows + other AAPCS functions to be called. +- If the CPU is M-class this is all that needs to be done since the architecture + itself is designed in such a way that functions obeying the normal AAPCS ABI + constraints are valid exception handlers. +- If the CPU is not M-class, the prologue and epilogue are modified to save all + non-banked registers that are used, so that upon return the user-mode state + will not be corrupted. Note that to avoid unnecessary overhead, only + general-purpose (integer) registers are saved in this way. If VFP operations + are needed, that state must be saved manually. + + Specifically, interrupt kinds other than "FIQ" will save all core registers + except "lr" and "sp". "FIQ" interrupts will save r0-r7. +- If the CPU is not M-class, the return instruction is changed to one of the + canonical sequences permitted by the architecture for exception return. Where + possible the function itself will make the necessary "lr" adjustments so that + the "preferred return address" is selected. + + Unfortunately the compiler is unable to make this guarantee for an "UNDEF" + handler, where the offset from "lr" to the preferred return address depends on + the execution state of the code which generated the exception. In this case + a sequence equivalent to "movs pc, lr" will be used. + + +abi_tag (gnu::abi_tag) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``abi_tag`` attribute can be applied to a function, variable, class or +inline namespace declaration to modify the mangled name of the entity. It gives +the ability to distinguish between different versions of the same entity but +with different ABI versions supported. For example, a newer version of a class +could have a different set of data members and thus have a different size. Using +the ``abi_tag`` attribute, it is possible to have different mangled names for +a global variable of the class type. Therefor, the old code could keep using +the old manged name and the new code will use the new mangled name with tags. + + +acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability) +----------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function as acquiring a capability. + + +interrupt +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on +x86/x86-64 targets.The compiler generates function entry and exit sequences +suitable for use in an interrupt handler when this attribute is present. +The 'IRET' instruction, instead of the 'RET' instruction, is used to return +from interrupt or exception handlers. All registers, except for the EFLAGS +register which is restored by the 'IRET' instruction, are preserved by the +compiler. + +Any interruptible-without-stack-switch code must be compiled with +-mno-red-zone since interrupt handlers can and will, because of the +hardware design, touch the red zone. + +1. interrupt handler must be declared with a mandatory pointer argument: + + .. code-block:: c + + struct interrupt_frame + { + uword_t ip; + uword_t cs; + uword_t flags; + uword_t sp; + uword_t ss; + }; + + __attribute__ ((interrupt)) + void f (struct interrupt_frame *frame) { + ... + } + +2. exception handler: + + The exception handler is very similar to the interrupt handler with + a different mandatory function signature: + + .. code-block:: c + + __attribute__ ((interrupt)) + void f (struct interrupt_frame *frame, uword_t error_code) { + ... + } + + and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction. + + The exception handler should only be used for exceptions which push an + error code and all other exceptions must use the interrupt handler. + The system will crash if the wrong handler is used. + + +assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability) +------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function that dynamically tests whether a capability is held, and halts +the program if it is not held. + + +assume_aligned (gnu::assume_aligned) +------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Use ``__attribute__((assume_aligned([,]))`` on a function +declaration to specify that the return value of the function (which must be a +pointer type) has the specified offset, in bytes, from an address with the +specified alignment. The offset is taken to be zero if omitted. + +.. code-block:: c++ + + // The returned pointer value has 32-byte alignment. + void *a() __attribute__((assume_aligned (32))); + + // The returned pointer value is 4 bytes greater than an address having + // 32-byte alignment. + void *b() __attribute__((assume_aligned (32, 4))); + +Note that this attribute provides information to the compiler regarding a +condition that the code already ensures is true. It does not cause the compiler +to enforce the provided alignment assumption. + + +availability +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The ``availability`` attribute can be placed on declarations to describe the +lifecycle of that declaration relative to operating system versions. Consider +the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7))); + +The availability attribute states that ``f`` was introduced in Mac OS X 10.4, +deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information +is used by Clang to determine when it is safe to use ``f``: for example, if +Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()`` +succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call +succeeds but Clang emits a warning specifying that the function is deprecated. +Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call +fails because ``f()`` is no longer available. + +The availability attribute is a comma-separated list starting with the +platform name and then including clauses specifying important milestones in the +declaration's lifetime (in any order) along with additional information. Those +clauses can be: + +introduced=\ *version* + The first version in which this declaration was introduced. + +deprecated=\ *version* + The first version in which this declaration was deprecated, meaning that + users should migrate away from this API. + +obsoleted=\ *version* + The first version in which this declaration was obsoleted, meaning that it + was removed completely and can no longer be used. + +unavailable + This declaration is never available on this platform. + +message=\ *string-literal* + Additional message text that Clang will provide when emitting a warning or + error about use of a deprecated or obsoleted declaration. Useful to direct + users to replacement APIs. + +replacement=\ *string-literal* + Additional message text that Clang will use to provide Fix-It when emitting + a warning about use of a deprecated declaration. The Fix-It will replace + the deprecated declaration with the new declaration specified. + +Multiple availability attributes can be placed on a declaration, which may +correspond to different platforms. Only the availability attribute with the +platform corresponding to the target platform will be used; any others will be +ignored. If no availability attribute specifies availability for the current +target platform, the availability attributes are ignored. Supported platforms +are: + +``ios`` + Apple's iOS operating system. The minimum deployment target is specified by + the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` + command-line arguments. + +``macos`` + Apple's Mac OS X operating system. The minimum deployment target is + specified by the ``-mmacosx-version-min=*version*`` command-line argument. + ``macosx`` is supported for backward-compatibility reasons, but it is + deprecated. + +``tvos`` + Apple's tvOS operating system. The minimum deployment target is specified by + the ``-mtvos-version-min=*version*`` command-line argument. + +``watchos`` + Apple's watchOS operating system. The minimum deployment target is specified by + the ``-mwatchos-version-min=*version*`` command-line argument. + +A declaration can typically be used even when deploying back to a platform +version prior to when the declaration was introduced. When this happens, the +declaration is `weakly linked +`_, +as if the ``weak_import`` attribute were added to the declaration. A +weakly-linked declaration may or may not be present a run-time, and a program +can determine whether the declaration is present by checking whether the +address of that declaration is non-NULL. + +The flag ``strict`` disallows using API when deploying back to a +platform version prior to when the declaration was introduced. An +attempt to use such API before its introduction causes a hard error. +Weakly-linking is almost always a better API choice, since it allows +users to query availability at runtime. + +If there are multiple declarations of the same entity, the availability +attributes must either match on a per-platform basis or later +declarations must not have availability attributes for that +platform. For example: + +.. code-block:: c + + void g(void) __attribute__((availability(macos,introduced=10.4))); + void g(void) __attribute__((availability(macos,introduced=10.4))); // okay, matches + void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform + void g(void); // okay, inherits both macos and ios availability from above. + void g(void) __attribute__((availability(macos,introduced=10.5))); // error: mismatch + +When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: + +.. code-block:: objc + + @interface A + - (id)method __attribute__((availability(macos,introduced=10.4))); + - (id)method2 __attribute__((availability(macos,introduced=10.4))); + @end + + @interface B : A + - (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later + - (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4 + @end + + +_Noreturn +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +A function declared as ``_Noreturn`` shall not return to its caller. The +compiler will generate a diagnostic for a function declared as ``_Noreturn`` +that appears to be capable of returning to its caller. + + +noreturn +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","X","","", "" + +A function declared as ``[[noreturn]]`` shall not return to its caller. The +compiler will generate a diagnostic for a function declared as ``[[noreturn]]`` +that appears to be capable of returning to its caller. + + +carries_dependency +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``carries_dependency`` attribute specifies dependency propagation into and +out of functions. + +When specified on a function or Objective-C method, the ``carries_dependency`` +attribute means that the return value carries a dependency out of the function, +so that the implementation need not constrain ordering upon return from that +function. Implementations of the function and its caller may choose to preserve +dependencies instead of emitting memory ordering instructions such as fences. + +Note, this attribute does not change the meaning of the program, but may result +in generation of more efficient code. + + +deprecated (gnu::deprecated) +---------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``deprecated`` attribute can be applied to a function, a variable, or a +type. This is useful when identifying functions, variables, or types that are +expected to be removed in a future version of a program. + +Consider the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((deprecated("message", "replacement"))); + +When spelled as `__attribute__((deprecated))`, the deprecated attribute can have +two optional string arguments. The first one is the message to display when +emitting the warning; the second one enables the compiler to provide a Fix-It +to replace the deprecated name with a new name. Otherwise, when spelled as +`[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional +string argument which is the message to display when emitting the warning. + + +disable_tail_calls (clang::disable_tail_calls) +---------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function. + +For example: + + .. code-block:: c + + int callee(int); + + int foo(int a) __attribute__((disable_tail_calls)) { + return callee(a); // This call is not tail-call optimized. + } + +Marking virtual functions as ``disable_tail_calls`` is legal. + + .. code-block:: c++ + + int callee(int); + + class Base { + public: + [[clang::disable_tail_calls]] virtual int foo1() { + return callee(); // This call is not tail-call optimized. + } + }; + + class Derived1 : public Base { + public: + int foo1() override { + return callee(); // This call is tail-call optimized. + } + }; + + +enable_if +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +.. Note:: Some features of this attribute are experimental. The meaning of + multiple enable_if attributes on a single declaration is subject to change in + a future version of clang. Also, the ABI is not standardized and the name + mangling may change in future versions. To avoid that, use asm labels. + +The ``enable_if`` attribute can be placed on function declarations to control +which overload is selected based on the values of the function's arguments. +When combined with the ``overloadable`` attribute, this feature is also +available in C. + +.. code-block:: c++ + + int isdigit(int c); + int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); + + void foo(char c) { + isdigit(c); + isdigit(10); + isdigit(-10); // results in a compile-time error. + } + +The enable_if attribute takes two arguments, the first is an expression written +in terms of the function parameters, the second is a string explaining why this +overload candidate could not be selected to be displayed in diagnostics. The +expression is part of the function signature for the purposes of determining +whether it is a redeclaration (following the rules used when determining +whether a C++ template specialization is ODR-equivalent), but is not part of +the type. + +The enable_if expression is evaluated as if it were the body of a +bool-returning constexpr function declared with the arguments of the function +it is being applied to, then called with the parameters at the call site. If the +result is false or could not be determined through constant expression +evaluation, then this overload will not be chosen and the provided string may +be used in a diagnostic if the compile fails as a result. + +Because the enable_if expression is an unevaluated context, there are no global +state changes, nor the ability to pass information from the enable_if +expression to the function body. For example, suppose we want calls to +strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of +strbuf) only if the size of strbuf can be determined: + +.. code-block:: c++ + + __attribute__((always_inline)) + static inline size_t strnlen(const char *s, size_t maxlen) + __attribute__((overloadable)) + __attribute__((enable_if(__builtin_object_size(s, 0) != -1))), + "chosen when the buffer size is known but 'maxlen' is not"))) + { + return strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); + } + +Multiple enable_if attributes may be applied to a single declaration. In this +case, the enable_if expressions are evaluated from left to right in the +following manner. First, the candidates whose enable_if expressions evaluate to +false or cannot be evaluated are discarded. If the remaining candidates do not +share ODR-equivalent enable_if expressions, the overload resolution is +ambiguous. Otherwise, enable_if overload resolution continues with the next +enable_if attribute on the candidates that have not been discarded and have +remaining enable_if attributes. In this way, we pick the most specific +overload out of a number of viable overloads using enable_if. + +.. code-block:: c++ + + void f() __attribute__((enable_if(true, ""))); // #1 + void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 + + void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 + void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 + +In this example, a call to f() is always resolved to #2, as the first enable_if +expression is ODR-equivalent for both declarations, but #1 does not have another +enable_if expression to continue evaluating, so the next round of evaluation has +only a single candidate. In a call to g(1, 1), the call is ambiguous even though +#2 has more enable_if attributes, because the first enable_if expressions are +not ODR-equivalent. + +Query for this feature with ``__has_attribute(enable_if)``. + +Note that functions with one or more ``enable_if`` attributes may not have +their address taken, unless all of the conditions specified by said +``enable_if`` are constants that evaluate to ``true``. For example: + +.. code-block:: c + + const int TrueConstant = 1; + const int FalseConstant = 0; + int f(int a) __attribute__((enable_if(a > 0, ""))); + int g(int a) __attribute__((enable_if(a == 0 || a != 0, ""))); + int h(int a) __attribute__((enable_if(1, ""))); + int i(int a) __attribute__((enable_if(TrueConstant, ""))); + int j(int a) __attribute__((enable_if(FalseConstant, ""))); + + void fn() { + int (*ptr)(int); + ptr = &f; // error: 'a > 0' is not always true + ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant + ptr = &h; // OK: 1 is a truthy constant + ptr = &i; // OK: 'TrueConstant' is a truthy constant + ptr = &j; // error: 'FalseConstant' is a constant, but not truthy + } + +Because ``enable_if`` evaluation happens during overload resolution, +``enable_if`` may give unintuitive results when used with templates, depending +on when overloads are resolved. In the example below, clang will emit a +diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``: + +.. code-block:: c++ + + double foo(int i) __attribute__((enable_if(i > 0, ""))); + void *foo(int i) __attribute__((enable_if(i <= 0, ""))); + template + auto bar() { return foo(I); } + + template + auto baz() { return foo(T::number); } + + struct WithNumber { constexpr static int number = 1; }; + void callThem() { + bar(); + baz(); + } + +This is because, in ``bar``, ``foo`` is resolved prior to template +instantiation, so the value for ``I`` isn't known (thus, both ``enable_if`` +conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during +template instantiation, so the value for ``T::number`` is known. + + +flatten (gnu::flatten) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``flatten`` attribute causes calls within the attributed function to +be inlined unless it is impossible to do so, for example if the body of the +callee is unavailable or if the callee has the ``noinline`` attribute. + + +format (gnu::format) +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Clang supports the ``format`` attribute, which indicates that the function +accepts a ``printf`` or ``scanf``-like format string and corresponding +arguments or a ``va_list`` that contains these arguments. + +Please see `GCC documentation about format attribute +`_ to find details +about attribute syntax. + +Clang implements two kinds of checks with this attribute. + +#. Clang checks that the function with the ``format`` attribute is called with + a format string that uses format specifiers that are allowed, and that + arguments match the format string. This is the ``-Wformat`` warning, it is + on by default. + +#. Clang checks that the format string argument is a literal string. This is + the ``-Wformat-nonliteral`` warning, it is off by default. + + Clang implements this mostly the same way as GCC, but there is a difference + for functions that accept a ``va_list`` argument (for example, ``vprintf``). + GCC does not emit ``-Wformat-nonliteral`` warning for calls to such + functions. Clang does not warn if the format string comes from a function + parameter, where the function is annotated with a compatible attribute, + otherwise it warns. For example: + + .. code-block:: c + + __attribute__((__format__ (__scanf__, 1, 3))) + void foo(const char* s, char *buf, ...) { + va_list ap; + va_start(ap, buf); + + vprintf(s, ap); // warning: format string is not a string literal + } + + In this case we warn because ``s`` contains a format string for a + ``scanf``-like function, but it is passed to a ``printf``-like function. + + If the attribute is removed, clang still warns, because the format string is + not a string literal. + + Another example: + + .. code-block:: c + + __attribute__((__format__ (__printf__, 1, 3))) + void foo(const char* s, char *buf, ...) { + va_list ap; + va_start(ap, buf); + + vprintf(s, ap); // warning + } + + In this case Clang does not warn because the format string ``s`` and + the corresponding arguments are annotated. If the arguments are + incorrect, the caller of ``foo`` will receive a warning. + + +ifunc (gnu::ifunc) +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. + +The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer. + +The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline. + +Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute. + + +internal_linkage (clang::internal_linkage) +------------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``internal_linkage`` attribute changes the linkage type of the declaration to internal. +This is similar to C-style ``static``, but can be used on classes and class methods. When applied to a class definition, +this attribute affects all methods and static data members of that class. +This can be used to contain the ABI of a C++ library by excluding unwanted class methods from the export tables. + + +interrupt +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on +MIPS targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +By default, the compiler will produce a function prologue and epilogue suitable for +an interrupt service routine that handles an External Interrupt Controller (eic) +generated interrupt. This behaviour can be explicitly requested with the "eic" +argument. + +Otherwise, for use with vectored interrupt mode, the argument passed should be +of the form "vector=LEVEL" where LEVEL is one of the following values: +"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will +then set the interrupt mask to the corresponding level which will mask all +interrupts up to and including the argument. + +The semantics are as follows: + +- The prologue is modified so that the Exception Program Counter (EPC) and + Status coprocessor registers are saved to the stack. The interrupt mask is + set so that the function can only be interrupted by a higher priority + interrupt. The epilogue will restore the previous values of EPC and Status. + +- The prologue and epilogue are modified to save and restore all non-kernel + registers as necessary. + +- The FPU is disabled in the prologue, as the floating pointer registers are not + spilled to the stack. + +- The function return sequence is changed to use an exception return instruction. + +- The parameter sets the interrupt mask for the function corresponding to the + interrupt level specified. If no mask is specified the interrupt mask + defaults to "eic". + + +noalias +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The ``noalias`` attribute indicates that the only memory accesses inside +function are loads and stores from objects pointed to by its pointer-typed +arguments, with arbitrary offsets. + + +noduplicate (clang::noduplicate) +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``noduplicate`` attribute can be placed on function declarations to control +whether function calls to this function can be duplicated or not as a result of +optimizations. This is required for the implementation of functions with +certain special requirements, like the OpenCL "barrier" function, that might +need to be run concurrently by all the threads that are executing in lockstep +on the hardware. For example this attribute applied on the function +"nodupfunc" in the code below avoids that: + +.. code-block:: c + + void nodupfunc() __attribute__((noduplicate)); + // Setting it as a C++11 attribute is also valid + // void nodupfunc() [[clang::noduplicate]]; + void foo(); + void bar(); + + nodupfunc(); + if (a > n) { + foo(); + } else { + bar(); + } + +gets possibly modified by some optimizations into code similar to this: + +.. code-block:: c + + if (a > n) { + nodupfunc(); + foo(); + } else { + nodupfunc(); + bar(); + } + +where the call to "nodupfunc" is duplicated and sunk into the two branches +of the condition. + + +no_sanitize (clang::no_sanitize) +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Use the ``no_sanitize`` attribute on a function declaration to specify +that a particular instrumentation or set of instrumentations should not be +applied to that function. The attribute takes a list of string literals, +which have the same meaning as values accepted by the ``-fno-sanitize=`` +flag. For example, ``__attribute__((no_sanitize("address", "thread")))`` +specifies that AddressSanitizer and ThreadSanitizer should not be applied +to the function. + +See :ref:`Controlling Code Generation ` for a +full list of supported sanitizer flags. + + +no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address) +----------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +.. _langext-address_sanitizer: + +Use ``__attribute__((no_sanitize_address))`` on a function declaration to +specify that address safety instrumentation (e.g. AddressSanitizer) should +not be applied to that function. + + +no_sanitize_thread +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +.. _langext-thread_sanitizer: + +Use ``__attribute__((no_sanitize_thread))`` on a function declaration to +specify that checks for data races on plain (non-atomic) memory accesses should +not be inserted by ThreadSanitizer. The function is still instrumented by the +tool to avoid false positives and provide meaningful stack traces. + + +no_sanitize_memory +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +.. _langext-memory_sanitizer: + +Use ``__attribute__((no_sanitize_memory))`` on a function declaration to +specify that checks for uninitialized memory should not be inserted +(e.g. by MemorySanitizer). The function may still be instrumented by the tool +to avoid false positives in other places. + + +no_split_stack (gnu::no_split_stack) +------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``no_split_stack`` attribute disables the emission of the split stack +preamble for a particular function. It has no effect if ``-fsplit-stack`` +is not specified. + + +not_tail_called (clang::not_tail_called) +---------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``not_tail_called`` attribute prevents tail-call optimization on statically bound calls. It has no effect on indirect calls. Virtual functions, objective-c methods, and functions marked as ``always_inline`` cannot be marked as ``not_tail_called``. + +For example, it prevents tail-call optimization in the following case: + + .. code-block:: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + return foo1(a); // No tail-call optimization on direct calls. + } + +However, it doesn't prevent tail-call optimization in this case: + + .. code-block:: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + int (*fn)(int) = &foo1; + + // not_tail_called has no effect on an indirect call even if the call can be + // resolved at compile time. + return (*fn)(a); + } + +Marking virtual functions as ``not_tail_called`` is an error: + + .. code-block:: c++ + + class Base { + public: + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] virtual int foo1(); + + virtual int foo2(); + + // Non-virtual functions can be marked ``not_tail_called``. + [[clang::not_tail_called]] int foo3(); + }; + + class Derived1 : public Base { + public: + int foo1() override; + + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] int foo2() override; + }; + + +#pragma omp declare simd +------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The `declare simd` construct can be applied to a function to enable the creation +of one or more versions that can process multiple arguments using SIMD +instructions from a single invocation in a SIMD loop. The `declare simd` +directive is a declarative directive. There may be multiple `declare simd` +directives for a function. The use of a `declare simd` construct on a function +enables the creation of SIMD versions of the associated function that can be +used to process multiple arguments from a single invocation from a SIMD loop +concurrently. +The syntax of the `declare simd` construct is as follows: + + .. code-block:: c + + #pragma omp declare simd [clause[[,] clause] ...] new-line + [#pragma omp declare simd [clause[[,] clause] ...] new-line] + [...] + function definition or declaration + +where clause is one of the following: + + .. code-block:: c + + simdlen(length) + linear(argument-list[:constant-linear-step]) + aligned(argument-list[:alignment]) + uniform(argument-list) + inbranch + notinbranch + + +#pragma omp declare target +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The `declare target` directive specifies that variables and functions are mapped +to a device for OpenMP offload mechanism. + +The syntax of the declare target directive is as follows: + + .. code-block:: c + + #pragma omp declare target new-line + declarations-definition-seq + #pragma omp end declare target new-line + + +objc_boxable +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Structs and unions marked with the ``objc_boxable`` attribute can be used +with the Objective-C boxed expression syntax, ``@(...)``. + +**Usage**: ``__attribute__((objc_boxable))``. This attribute +can only be placed on a declaration of a trivially-copyable struct or union: + +.. code-block:: objc + + struct __attribute__((objc_boxable)) some_struct { + int i; + }; + union __attribute__((objc_boxable)) some_union { + int i; + float f; + }; + typedef struct __attribute__((objc_boxable)) _some_struct some_struct; + + // ... + + some_struct ss; + NSValue *boxed = @(ss); + + +objc_method_family +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Many methods in Objective-C have conventional meanings determined by their +selectors. It is sometimes useful to be able to mark a method as having a +particular conventional meaning despite not having the right selector, or as +not having the conventional meaning that its selector would suggest. For these +use cases, we provide an attribute to specifically describe the "method family" +that a method belongs to. + +**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of +``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This +attribute can only be placed at the end of a method declaration: + +.. code-block:: objc + + - (NSString *)initMyStringValue __attribute__((objc_method_family(none))); + +Users who do not wish to change the conventional meaning of a method, and who +merely want to document its non-standard retain and release semantics, should +use the retaining behavior attributes (``ns_returns_retained``, +``ns_returns_not_retained``, etc). + +Query for this feature with ``__has_attribute(objc_method_family)``. + + +objc_requires_super +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Some Objective-C classes allow a subclass to override a particular method in a +parent class but expect that the overriding method also calls the overridden +method in the parent class. For these cases, we provide an attribute to +designate that a method requires a "call to ``super``" in the overriding +method in the subclass. + +**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only +be placed at the end of a method declaration: + +.. code-block:: objc + + - (void)foo __attribute__((objc_requires_super)); + +This attribute can only be applied the method declarations within a class, and +not a protocol. Currently this attribute does not enforce any placement of +where the call occurs in the overriding method (such as in the case of +``-dealloc`` where the call must appear at the end). It checks only that it +exists. + +Note that on both OS X and iOS that the Foundation framework provides a +convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this +attribute: + +.. code-block:: objc + + - (void)foo NS_REQUIRES_SUPER; + +This macro is conditionally defined depending on the compiler's support for +this attribute. If the compiler does not support the attribute the macro +expands to nothing. + +Operationally, when a method has this annotation the compiler will warn if the +implementation of an override in a subclass does not call super. For example: + +.. code-block:: objc + + warning: method possibly missing a [super AnnotMeth] call + - (void) AnnotMeth{}; + ^ + + +objc_runtime_name +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +By default, the Objective-C interface or protocol identifier is used +in the metadata name for that object. The `objc_runtime_name` +attribute allows annotated interfaces or protocols to use the +specified string argument in the object's metadata name instead of the +default name. + +**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute +can only be placed before an @protocol or @interface declaration: + +.. code-block:: objc + + __attribute__((objc_runtime_name("MyLocalName"))) + @interface Message + @end + + +objc_runtime_visible +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. + + +optnone (clang::optnone) +------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``optnone`` attribute suppresses essentially all optimizations +on a function or method, regardless of the optimization level applied to +the compilation unit as a whole. This is particularly useful when you +need to debug a particular function, but it is infeasible to build the +entire application without optimization. Avoiding optimization on the +specified function can improve the quality of the debugging information +for that function. + +This attribute is incompatible with the ``always_inline`` and ``minsize`` +attributes. + + +overloadable +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang provides support for C++ function overloading in C. Function overloading +in C is introduced using the ``overloadable`` attribute. For example, one +might provide several overloaded versions of a ``tgsin`` function that invokes +the appropriate standard function computing the sine of a value with ``float``, +``double``, or ``long double`` precision: + +.. code-block:: c + + #include + float __attribute__((overloadable)) tgsin(float x) { return sinf(x); } + double __attribute__((overloadable)) tgsin(double x) { return sin(x); } + long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); } + +Given these declarations, one can call ``tgsin`` with a ``float`` value to +receive a ``float`` result, with a ``double`` to receive a ``double`` result, +etc. Function overloading in C follows the rules of C++ function overloading +to pick the best overload given the call arguments, with a few C-specific +semantics: + +* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a + floating-point promotion (per C99) rather than as a floating-point conversion + (as in C++). + +* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is + considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are + compatible types. + +* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T`` + and ``U`` are compatible types. This conversion is given "conversion" rank. + +The declaration of ``overloadable`` functions is restricted to function +declarations and definitions. Most importantly, if any function with a given +name is given the ``overloadable`` attribute, then all function declarations +and definitions with that name (and in that scope) must have the +``overloadable`` attribute. This rule even applies to redeclarations of +functions whose original declaration had the ``overloadable`` attribute, e.g., + +.. code-block:: c + + int f(int) __attribute__((overloadable)); + float f(float); // error: declaration of "f" must have the "overloadable" attribute + + int g(int) __attribute__((overloadable)); + int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute + +Functions marked ``overloadable`` must have prototypes. Therefore, the +following code is ill-formed: + +.. code-block:: c + + int h() __attribute__((overloadable)); // error: h does not have a prototype + +However, ``overloadable`` functions are allowed to use a ellipsis even if there +are no named parameters (as is permitted in C++). This feature is particularly +useful when combined with the ``unavailable`` attribute: + +.. code-block:: c++ + + void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error + +Functions declared with the ``overloadable`` attribute have their names mangled +according to the same rules as C++ function names. For example, the three +``tgsin`` functions in our motivating example get the mangled names +``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two +caveats to this use of name mangling: + +* Future versions of Clang may change the name mangling of functions overloaded + in C, so you should not depend on an specific mangling. To be completely + safe, we strongly urge the use of ``static inline`` with ``overloadable`` + functions. + +* The ``overloadable`` attribute has almost no meaning when used in C++, + because names will already be mangled and functions are already overloadable. + However, when an ``overloadable`` function occurs within an ``extern "C"`` + linkage specification, it's name *will* be mangled in the same way as it + would in C. + +Query for this feature with ``__has_extension(attribute_overloadable)``. + + +release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability) +----------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function as releasing a capability. + + +kernel +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +``__attribute__((kernel))`` is used to mark a ``kernel`` function in +RenderScript. + +In RenderScript, ``kernel`` functions are used to express data-parallel +computations. The RenderScript runtime efficiently parallelizes ``kernel`` +functions to run on computational resources such as multi-core CPUs and GPUs. +See the RenderScript_ documentation for more information. + +.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html + + +target (gnu::target) +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute. +This attribute may be attached to a function definition and instructs +the backend to use different code generation options than were passed on the +command line. + +The current set of options correspond to the existing "subtarget features" for +the target with or without a "-mno-" in front corresponding to the absence +of the feature, as well as ``arch="CPU"`` which will change the default "CPU" +for the function. + +Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", +"avx", "xop" and largely correspond to the machine specific options handled by +the front end. + + +try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability) +--------------------------------------------------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Marks a function that attempts to acquire a capability. This function may fail to +actually acquire the capability; they accept a Boolean value determining +whether acquiring the capability means success (true), or failing to acquire +the capability means success (false). + + +nodiscard, warn_unused_result, clang::warn_unused_result, gnu::warn_unused_result +--------------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +Clang supports the ability to diagnose when the results of a function call +expression are discarded under suspicious circumstances. A diagnostic is +generated when a function or its return type is marked with ``[[nodiscard]]`` +(or ``__attribute__((warn_unused_result))``) and the function call appears as a +potentially-evaluated discarded-value expression that is not explicitly cast to +`void`. + +.. code-block: c++ + struct [[nodiscard]] error_info { /*...*/ }; + error_info enable_missile_safety_mode(); + + void launch_missiles(); + void test_missiles() { + enable_missile_safety_mode(); // diagnoses + launch_missiles(); + } + error_info &foo(); + void f() { foo(); } // Does not diagnose, error_info is a reference. + + +xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument) +------------------------------------------------------------------------------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. + +Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. + +If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. + + +Variable Attributes +=================== + + +dllexport (gnu::dllexport) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``__declspec(dllexport)`` attribute declares a variable, function, or +Objective-C interface to be exported from the module. It is available under the +``-fdeclspec`` flag for compatibility with various compilers. The primary use +is for COFF object files which explicitly specify what interfaces are available +for external use. See the dllexport_ documentation on MSDN for more +information. + +.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + + +dllimport (gnu::dllimport) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``__declspec(dllimport)`` attribute declares a variable, function, or +Objective-C interface to be imported from an external module. It is available +under the ``-fdeclspec`` flag for compatibility with various compilers. The +primary use is for COFF object files which explicitly specify what interfaces +are imported from external modules. See the dllimport_ documentation on MSDN +for more information. + +.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + + +init_seg +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The attribute applied by ``pragma init_seg()`` controls the section into +which global initialization function pointers are emitted. It is only +available with ``-fms-extensions``. Typically, this function pointer is +emitted into ``.CRT$XCU`` on Windows. The user can change the order of +initialization by using a different section name with the same +``.CRT$XC`` prefix and a suffix that sorts lexicographically before or +after the standard ``.CRT$XCU`` sections. See the init_seg_ +documentation on MSDN for more information. + +.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx + + +nodebug (gnu::nodebug) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``nodebug`` attribute allows you to suppress debugging information for a +function or method, or for a variable that is not a parameter or a non-static +data member. + + +nosvm +----- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +OpenCL 2.0 supports the optional ``__attribute__((nosvm))`` qualifier for +pointer variable. It informs the compiler that the pointer does not refer +to a shared virtual memory region. See OpenCL v2.0 s6.7.2 for details. + +Since it is not widely used and has been removed from OpenCL 2.1, it is ignored +by Clang. + + +pass_object_size +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +.. Note:: The mangling of functions with parameters that are annotated with + ``pass_object_size`` is subject to change. You can get around this by + using ``__asm__("foo")`` to explicitly name your functions, thus preserving + your ABI; also, non-overloadable C functions with ``pass_object_size`` are + not mangled. + +The ``pass_object_size(Type)`` attribute can be placed on function parameters to +instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite +of said function, and implicitly pass the result of this call in as an invisible +argument of type ``size_t`` directly after the parameter annotated with +``pass_object_size``. Clang will also replace any calls to +``__builtin_object_size(param, Type)`` in the function by said implicit +parameter. + +Example usage: + +.. code-block:: c + + int bzero1(char *const p __attribute__((pass_object_size(0)))) + __attribute__((noinline)) { + int i = 0; + for (/**/; i < (int)__builtin_object_size(p, 0); ++i) { + p[i] = 0; + } + return i; + } + + int main() { + char chars[100]; + int n = bzero1(&chars[0]); + assert(n == sizeof(chars)); + return 0; + } + +If successfully evaluating ``__builtin_object_size(param, Type)`` at the +callsite is not possible, then the "failed" value is passed in. So, using the +definition of ``bzero1`` from above, the following code would exit cleanly: + +.. code-block:: c + + int main2(int argc, char *argv[]) { + int n = bzero1(argv); + assert(n == -1); + return 0; + } + +``pass_object_size`` plays a part in overload resolution. If two overload +candidates are otherwise equally good, then the overload with one or more +parameters with ``pass_object_size`` is preferred. This implies that the choice +between two identical overloads both with ``pass_object_size`` on one or more +parameters will always be ambiguous; for this reason, having two such overloads +is illegal. For example: + +.. code-block:: c++ + + #define PS(N) __attribute__((pass_object_size(N))) + // OK + void Foo(char *a, char *b); // Overload A + // OK -- overload A has no parameters with pass_object_size. + void Foo(char *a PS(0), char *b PS(0)); // Overload B + // Error -- Same signature (sans pass_object_size) as overload B, and both + // overloads have one or more parameters with the pass_object_size attribute. + void Foo(void *a PS(0), void *b); + + // OK + void Bar(void *a PS(0)); // Overload C + // OK + void Bar(char *c PS(1)); // Overload D + + void main() { + char known[10], *unknown; + Foo(unknown, unknown); // Calls overload B + Foo(known, unknown); // Calls overload B + Foo(unknown, known); // Calls overload B + Foo(known, known); // Calls overload B + + Bar(known); // Calls overload D + Bar(unknown); // Calls overload D + } + +Currently, ``pass_object_size`` is a bit restricted in terms of its usage: + +* Only one use of ``pass_object_size`` is allowed per parameter. + +* It is an error to take the address of a function with ``pass_object_size`` on + any of its parameters. If you wish to do this, you can create an overload + without ``pass_object_size`` on any parameters. + +* It is an error to apply the ``pass_object_size`` attribute to parameters that + are not pointers. Additionally, any parameter that ``pass_object_size`` is + applied to must be marked ``const`` at its function's definition. + + +section (gnu::section, __declspec(allocate)) +-------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","X","", "" + +The ``section`` attribute allows you to specify a specific section a +global variable or function should be in after translation. + + +swiftcall (gnu::swiftcall) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swiftcall`` attribute indicates that a function should be called +using the Swift calling convention for a function or function pointer. + +The lowering for the Swift calling convention, as described by the Swift +ABI documentation, occurs in multiple phases. The first, "high-level" +phase breaks down the formal parameters and results into innately direct +and indirect components, adds implicit paraameters for the generic +signature, and assigns the context and error ABI treatments to parameters +where applicable. The second phase breaks down the direct parameters +and results from the first phase and assigns them to registers or the +stack. The ``swiftcall`` convention only handles this second phase of +lowering; the C function type must accurately reflect the results +of the first phase, as follows: + +- Results classified as indirect by high-level lowering should be + represented as parameters with the ``swift_indirect_result`` attribute. + +- Results classified as direct by high-level lowering should be represented + as follows: + + - First, remove any empty direct results. + + - If there are no direct results, the C result type should be ``void``. + + - If there is one direct result, the C result type should be a type with + the exact layout of that result type. + + - If there are a multiple direct results, the C result type should be + a struct type with the exact layout of a tuple of those results. + +- Parameters classified as indirect by high-level lowering should be + represented as parameters of pointer type. + +- Parameters classified as direct by high-level lowering should be + omitted if they are empty types; otherwise, they should be represented + as a parameter type with a layout exactly matching the layout of the + Swift parameter type. + +- The context parameter, if present, should be represented as a trailing + parameter with the ``swift_context`` attribute. + +- The error result parameter, if present, should be represented as a + trailing parameter (always following a context parameter) with the + ``swift_error_result`` attribute. + +``swiftcall`` does not support variadic arguments or unprototyped functions. + +The parameter ABI treatment attributes are aspects of the function type. +A function type which which applies an ABI treatment attribute to a +parameter is a different type from an otherwise-identical function type +that does not. A single parameter may not have multiple ABI treatment +attributes. + +Support for this feature is target-dependent, although it should be +supported on every target that Swift supports. Query for this support +with ``__has_attribute(swiftcall)``. This implies support for the +``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` +attributes. + + +swift_context (gnu::swift_context) +---------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swift_context`` attribute marks a parameter of a ``swiftcall`` +function as having the special context-parameter ABI treatment. + +This treatment generally passes the context value in a special register +which is normally callee-preserved. + +A ``swift_context`` parameter must either be the last parameter or must be +followed by a ``swift_error_result`` parameter (which itself must always be +the last parameter). + +A context parameter must have pointer or reference type. + + +swift_error_result (gnu::swift_error_result) +-------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swift_error_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special error-result ABI treatment. + +This treatment generally passes the underlying error value in and out of +the function through a special register which is normally callee-preserved. +This is modeled in C by pretending that the register is addressable memory: + +- The caller appears to pass the address of a variable of pointer type. + The current value of this variable is copied into the register before + the call; if the call returns normally, the value is copied back into the + variable. + +- The callee appears to receive the address of a variable. This address + is actually a hidden location in its own stack, initialized with the + value of the register upon entry. When the function returns normally, + the value in that hidden location is written back to the register. + +A ``swift_error_result`` parameter must be the last parameter, and it must be +preceded by a ``swift_context`` parameter. + +A ``swift_error_result`` parameter must have type ``T**`` or ``T*&`` for some +type T. Note that no qualifiers are permitted on the intermediate level. + +It is undefined behavior if the caller does not pass a pointer or +reference to a valid object. + +The standard convention is that the error value itself (that is, the +value stored in the apparent argument) will be null upon function entry, +but this is not enforced by the ABI. + + +swift_indirect_result (gnu::swift_indirect_result) +-------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special indirect-result ABI treatmenet. + +This treatment gives the parameter the target's normal indirect-result +ABI treatment, which may involve passing it differently from an ordinary +parameter. However, only the first indirect result will receive this +treatment. Furthermore, low-level lowering may decide that a direct result +must be returned indirectly; if so, this will take priority over the +``swift_indirect_result`` parameters. + +A ``swift_indirect_result`` parameter must either be the first parameter or +follow another ``swift_indirect_result`` parameter. + +A ``swift_indirect_result`` parameter must have type ``T*`` or ``T&`` for +some object type ``T``. If ``T`` is a complete type at the point of +definition of a function, it is undefined behavior if the argument +value does not point to storage of adequate size and alignment for a +value of type ``T``. + +Making indirect results explicit in the signature allows C functions to +directly construct objects into them without relying on language +optimizations like C++'s named return value optimization (NRVO). + + +tls_model (gnu::tls_model) +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``tls_model`` attribute allows you to specify which thread-local storage +model to use. It accepts the following strings: + +* global-dynamic +* local-dynamic +* initial-exec +* local-exec + +TLS models are mutually exclusive. + + +thread +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The ``__declspec(thread)`` attribute declares a variable with thread local +storage. It is available under the ``-fms-extensions`` flag for MSVC +compatibility. See the documentation for `__declspec(thread)`_ on MSDN. + +.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx + +In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the +GNU ``__thread`` keyword. The variable must not have a destructor and must have +a constant initializer, if any. The attribute only applies to variables +declared with static storage duration, such as globals, class static data +members, and static locals. + + +maybe_unused, unused, gnu::unused +--------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +When passing the ``-Wunused`` flag to Clang, entities that are unused by the +program may be diagnosed. The ``[[maybe_unused]]`` (or +``__attribute__((unused))``) attribute can be used to silence such diagnostics +when the entity cannot be removed. For instance, a local variable may exist +solely for use in an ``assert()`` statement, which makes the local variable +unused when ``NDEBUG`` is defined. + +The attribute may be applied to the declaration of a class, a typedef, a +variable, a function or method, a function parameter, an enumeration, an +enumerator, a non-static data member, or a label. + +.. code-block: c++ + #include + + [[maybe_unused]] void f([[maybe_unused]] bool thing1, + [[maybe_unused]] bool thing2) { + [[maybe_unused]] bool b = thing1 && thing2; + assert(b); + } + + +Type Attributes +=============== + + +align_value +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The align_value attribute can be added to the typedef of a pointer type or the +declaration of a variable of pointer or reference type. It specifies that the +pointer will point to, or the reference will bind to, only objects with at +least the provided alignment. This alignment value must be some positive power +of 2. + + .. code-block:: c + + typedef double * aligned_double_ptr __attribute__((align_value(64))); + void foo(double & x __attribute__((align_value(128)), + aligned_double_ptr y) { ... } + +If the pointer value does not have the specified alignment at runtime, the +behavior of the program is undefined. + + +empty_bases +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The empty_bases attribute permits the compiler to utilize the +empty-base-optimization more frequently. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + + +flag_enum +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +This attribute can be added to an enumerator to signal to the compiler that it +is intended to be used as a flag type. This will cause the compiler to assume +that the range of the type includes all of the values that you can get by +manipulating bits of the enumerator when issuing warnings. + + +lto_visibility_public (clang::lto_visibility_public) +---------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","X","","", "" + +See :doc:`LTOVisibility`. + + +layout_version +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +The layout_version attribute requests that the compiler utilize the class +layout rules of a particular compiler version. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + + +__single_inhertiance, __multiple_inheritance, __virtual_inheritance +------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +This collection of keywords is enabled under ``-fms-extensions`` and controls +the pointer-to-member representation used on ``*-*-win32`` targets. + +The ``*-*-win32`` targets utilize a pointer-to-member representation which +varies in size and alignment depending on the definition of the underlying +class. + +However, this is problematic when a forward declaration is only available and +no definition has been made yet. In such cases, Clang is forced to utilize the +most general representation that is available to it. + +These keywords make it possible to use a pointer-to-member representation other +than the most general one regardless of whether or not the definition will ever +be present in the current translation unit. + +This family of keywords belong between the ``class-key`` and ``class-name``: + +.. code-block:: c++ + + struct __single_inheritance S; + int S::*i; + struct S {}; + +This keyword can be applied to class templates but only has an effect when used +on full specializations: + +.. code-block:: c++ + + template struct __single_inheritance A; // warning: inheritance model ignored on primary template + template struct __multiple_inheritance A; // warning: inheritance model ignored on partial specialization + template <> struct __single_inheritance A; + +Note that choosing an inheritance model less general than strictly necessary is +an error: + +.. code-block:: c++ + + struct __multiple_inheritance S; // error: inheritance model does not match definition + int S::*i; + struct S {}; + + +novtable +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","X","", "" + +This attribute can be added to a class declaration or definition to signal to +the compiler that constructors and destructors will not reference the virtual +function table. It is only supported when using the Microsoft C++ ABI. + + +Statement Attributes +==================== + + +fallthrough, clang::fallthrough +------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","X","","", "" + +The ``fallthrough`` (or ``clang::fallthrough``) attribute is used +to annotate intentional fall-through +between switch labels. It can only be applied to a null statement placed at a +point of execution between any statement and the next switch label. It is +common to mark these places with a specific comment, but this attribute is +meant to replace comments with a more strict annotation, which can be checked +by the compiler. This attribute doesn't change semantics of the code and can +be used wherever an intended fall-through occurs. It is designed to mimic +control-flow statements like ``break;``, so it can be placed in most places +where ``break;`` can, but only if there are no statements on the execution path +between it and the next switch label. + +By default, Clang does not warn on unannotated fallthrough from one ``switch`` +case to another. Diagnostics on fallthrough without a corresponding annotation +can be enabled with the ``-Wimplicit-fallthrough`` argument. + +Here is an example: + +.. code-block:: c++ + + // compile with -Wimplicit-fallthrough + switch (n) { + case 22: + case 33: // no warning: no statements between case labels + f(); + case 44: // warning: unannotated fall-through + g(); + [[clang::fallthrough]]; + case 55: // no warning + if (x) { + h(); + break; + } + else { + i(); + [[clang::fallthrough]]; + } + case 66: // no warning + p(); + [[clang::fallthrough]]; // warning: fallthrough annotation does not + // directly precede case label + q(); + case 77: // warning: unannotated fall-through + r(); + } + + +#pragma clang loop +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +The ``#pragma clang loop`` directive allows loop optimization hints to be +specified for the subsequent loop. The directive allows vectorization, +interleaving, and unrolling to be enabled or disabled. Vector width as well +as interleave and unrolling count can be manually specified. See +`language extensions +`_ +for details. + + +#pragma unroll, #pragma nounroll +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","", "X" + +Loop unrolling optimization hints can be specified with ``#pragma unroll`` and +``#pragma nounroll``. The pragma is placed immediately before a for, while, +do-while, or c++11 range-based for loop. + +Specifying ``#pragma unroll`` without a parameter directs the loop unroller to +attempt to fully unroll the loop if the trip count is known at compile time and +attempt to partially unroll the loop if the trip count is not known at compile +time: + +.. code-block:: c++ + + #pragma unroll + for (...) { + ... + } + +Specifying the optional parameter, ``#pragma unroll _value_``, directs the +unroller to unroll the loop ``_value_`` times. The parameter may optionally be +enclosed in parentheses: + +.. code-block:: c++ + + #pragma unroll 16 + for (...) { + ... + } + + #pragma unroll(16) + for (...) { + ... + } + +Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled: + +.. code-block:: c++ + + #pragma nounroll + for (...) { + ... + } + +``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to +``#pragma clang loop unroll(full)`` and +``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll`` +is equivalent to ``#pragma clang loop unroll(disable)``. See +`language extensions +`_ +for further details including limitations of the unroll hints. + + +__read_only, __write_only, __read_write (read_only, write_only, read_write) +--------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The access qualifiers must be used with image object arguments or pipe arguments +to declare if they are being read or written by a kernel or function. + +The read_only/__read_only, write_only/__write_only and read_write/__read_write +names are reserved for use as access qualifiers and shall not be used otherwise. + +.. code-block:: c + + kernel void + foo (read_only image2d_t imageA, + write_only image2d_t imageB) { + ... + } + +In the above example imageA is a read-only 2D image object, and imageB is a +write-only 2D image object. + +The read_write (or __read_write) qualifier can not be used with pipe. + +More details can be found in the OpenCL C language Spec v2.0, Section 6.6. + + +__attribute__((opencl_unroll_hint)) +----------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The opencl_unroll_hint attribute qualifier can be used to specify that a loop +(for, while and do loops) can be unrolled. This attribute qualifier can be +used to specify full unrolling or partial unrolling by a specified amount. +This is a compiler hint and the compiler may ignore this directive. See +`OpenCL v2.0 `_ +s6.11.5 for details. + + +AMD GPU Register Attributes +=========================== +Clang supports attributes for controlling register usage on AMD GPU +targets. These attributes may be attached to a kernel function +definition and is an optimization hint to the backend for the maximum +number of registers to use. This is useful in cases where register +limited occupancy is known to be an important factor for the +performance for the kernel. + +The semantics are as follows: + +- The backend will attempt to limit the number of used registers to + the specified value, but the exact number used is not + guaranteed. The number used may be rounded up to satisfy the + allocation requirements or ABI constraints of the subtarget. For + example, on Southern Islands VGPRs may only be allocated in + increments of 4, so requesting a limit of 39 VGPRs will really + attempt to use up to 40. Requesting more registers than the + subtarget supports will truncate to the maximum allowed. The backend + may also use fewer registers than requested whenever possible. + +- 0 implies the default no limit on register usage. + +- Ignored on older VLIW subtargets which did not have separate scalar + and vector registers, R600 through Northern Islands. + +amdgpu_num_sgpr +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the +``__attribute__((amdgpu_num_sgpr()))`` attribute on AMD +Southern Islands GPUs and later for controlling the number of scalar +registers. A typical value would be between 8 and 104 in increments of +8. + +Due to common instruction constraints, an additional 2-4 SGPRs are +typically required for internal use depending on features used. This +value is a hint for the total number of SGPRs to use, and not the +number of user SGPRs, so no special consideration needs to be given +for these. + + +amdgpu_num_vgpr +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports the +``__attribute__((amdgpu_num_vgpr()))`` attribute on AMD +Southern Islands GPUs and later for controlling the number of vector +registers. A typical value would be between 4 and 256 in increments +of 4. + + +Calling Conventions +=================== +Clang supports several different calling conventions, depending on the target +platform and architecture. The calling convention used for a function determines +how parameters are passed, how results are returned to the caller, and other +low-level details of calling a function. + +fastcall (gnu::fastcall, __fastcall, _fastcall) +----------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","X", "" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to use ECX and EDX as register parameters and clear parameters off of +the stack on return. This convention does not support variadic calls or +unprototyped functions in C, and has no effect on x86_64 targets. This calling +convention is supported primarily for compatibility with existing code. Users +seeking register parameters should use the ``regparm`` attribute, which does +not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN. + +.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx + + +ms_abi (gnu::ms_abi) +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +On non-Windows x86_64 targets, this attribute changes the calling convention of +a function to match the default convention used on Windows x86_64. This +attribute has no effect on Windows targets or non-x86_64 targets. + + +pcs (gnu::pcs) +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +On ARM targets, this attribute can be used to select calling conventions +similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and +"aapcs-vfp". + + +preserve_all +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_all`` calling convention attempts to make the code +in the caller even less intrusive than the ``preserve_most`` calling convention. +This calling convention also behaves identical to the ``C`` calling convention +on how arguments and return values are passed, but it uses a different set of +caller/callee-saved registers. This removes the burden of saving and +recovering a large register set before and after the call in the caller. If +the arguments are passed in callee-saved registers, then they will be +preserved by the callee across the call. This doesn't apply for values +returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Furthermore it also preserves + all floating-point registers (XMMs/YMMs). + +The idea behind this convention is to support calls to runtime functions +that don't need to call out to any other functions. + +This calling convention, like the ``preserve_most`` calling convention, will be +used by a future version of the Objective-C runtime and should be considered +experimental at this time. + + +preserve_most +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_most`` calling convention attempts to make the code +in the caller as unintrusive as possible. This convention behaves identically +to the ``C`` calling convention on how arguments and return values are passed, +but it uses a different set of caller/callee-saved registers. This alleviates +the burden of saving and recovering a large register set before and after the +call in the caller. If the arguments are passed in callee-saved registers, +then they will be preserved by the callee across the call. This doesn't +apply for values returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Floating-point registers + (XMMs/YMMs) are not preserved and need to be saved by the caller. + +The idea behind this convention is to support calls to runtime functions +that have a hot path and a cold path. The hot path is usually a small piece +of code that doesn't use many registers. The cold path might need to call out to +another function and therefore only needs to preserve the caller-saved +registers, which haven't already been saved by the caller. The +`preserve_most` calling convention is very similar to the ``cold`` calling +convention in terms of caller/callee-saved registers, but they are used for +different types of function calls. ``coldcc`` is for function calls that are +rarely executed, whereas `preserve_most` function calls are intended to be +on the hot path and definitely executed a lot. Furthermore ``preserve_most`` +doesn't prevent the inliner from inlining the function call. + +This calling convention will be used by a future version of the Objective-C +runtime and should therefore still be considered experimental at this time. +Although this convention was created to optimize certain runtime calls to +the Objective-C runtime, it is not limited to this runtime and might be used +by other runtimes in the future too. The current implementation only +supports X86-64 and AArch64, but the intention is to support more architectures +in the future. + + +regparm (gnu::regparm) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +On 32-bit x86 targets, the regparm attribute causes the compiler to pass +the first three integer parameters in EAX, EDX, and ECX instead of on the +stack. This attribute has no effect on variadic functions, and all parameters +are passed via the stack as normal. + + +stdcall (gnu::stdcall, __stdcall, _stdcall) +------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","X", "" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to clear parameters off of the stack on return. This convention does +not support variadic calls or unprototyped functions in C, and has no effect on +x86_64 targets. This calling convention is used widely by the Windows API and +COM applications. See the documentation for `__stdcall`_ on MSDN. + +.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx + + +thiscall (gnu::thiscall, __thiscall, _thiscall) +----------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","X", "" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to use ECX for the first parameter (typically the implicit ``this`` +parameter of C++ methods) and clear parameters off of the stack on return. This +convention does not support variadic calls or unprototyped functions in C, and +has no effect on x86_64 targets. See the documentation for `__thiscall`_ on +MSDN. + +.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx + + +vectorcall (__vectorcall, _vectorcall) +-------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","X", "" + +On 32-bit x86 *and* x86_64 targets, this attribute changes the calling +convention of a function to pass vector parameters in SSE registers. + +On 32-bit x86 targets, this calling convention is similar to ``__fastcall``. +The first two integer parameters are passed in ECX and EDX. Subsequent integer +parameters are passed in memory, and callee clears the stack. On x86_64 +targets, the callee does *not* clear the stack, and integer parameters are +passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling +convention. + +On both 32-bit x86 and x86_64 targets, vector and floating point arguments are +passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are +passed in sequential SSE registers if enough are available. If AVX is enabled, +256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that +cannot be passed in registers for any reason is passed by reference, which +allows the caller to align the parameter memory. + +See the documentation for `__vectorcall`_ on MSDN for more details. + +.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx + + +Consumed Annotation Checking +============================ +Clang supports additional attributes for checking basic resource management +properties, specifically for unique objects that have a single owning reference. +The following attributes are currently supported, although **the implementation +for these annotations is currently in development and are subject to change.** + +callable_when +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((callable_when(...)))`` to indicate what states a method +may be called in. Valid states are unconsumed, consumed, or unknown. Each +argument to this attribute must be a quoted string. E.g.: + +``__attribute__((callable_when("unconsumed", "unknown")))`` + + +consumable +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Each ``class`` that uses any of the typestate annotations must first be marked +using the ``consumable`` attribute. Failure to do so will result in a warning. + +This attribute accepts a single parameter that must be one of the following: +``unknown``, ``consumed``, or ``unconsumed``. + + +param_typestate +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +This attribute specifies expectations about function parameters. Calls to an +function with annotated parameters will issue a warning if the corresponding +argument isn't in the expected state. The attribute is also used to set the +initial state of the parameter when analyzing the function's body. + + +return_typestate +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +The ``return_typestate`` attribute can be applied to functions or parameters. +When applied to a function the attribute specifies the state of the returned +value. The function's body is checked to ensure that it always returns a value +in the specified state. On the caller side, values returned by the annotated +function are initialized to the given state. + +When applied to a function parameter it modifies the state of an argument after +a call to the function returns. The function's body is checked to ensure that +the parameter is in the expected state before returning. + + +set_typestate +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Annotate methods that transition an object into a new state with +``__attribute__((set_typestate(new_state)))``. The new state must be +unconsumed, consumed, or unknown. + + +test_typestate +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method +returns true if the object is in the specified state.. + + +Type Safety Checking +==================== +Clang supports additional attributes to enable checking type safety properties +that can't be enforced by the C type system. Use cases include: + +* MPI library implementations, where these attributes enable checking that + the buffer type matches the passed ``MPI_Datatype``; +* for HDF5 library there is a similar use case to MPI; +* checking types of variadic functions' arguments for functions like + ``fcntl()`` and ``ioctl()``. + +You can detect support for these attributes with ``__has_attribute()``. For +example: + +.. code-block:: c++ + + #if defined(__has_attribute) + # if __has_attribute(argument_with_type_tag) && \ + __has_attribute(pointer_with_type_tag) && \ + __has_attribute(type_tag_for_datatype) + # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) + /* ... other macros ... */ + # endif + #endif + + #if !defined(ATTR_MPI_PWT) + # define ATTR_MPI_PWT(buffer_idx, type_idx) + #endif + + int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) + ATTR_MPI_PWT(1,3); + +argument_with_type_tag +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx, +type_tag_idx)))`` on a function declaration to specify that the function +accepts a type tag that determines the type of some other argument. +``arg_kind`` is an identifier that should be used when annotating all +applicable type tags. + +This attribute is primarily useful for checking arguments of variadic functions +(``pointer_with_type_tag`` can be used in most non-variadic cases). + +For example: + +.. code-block:: c++ + + int fcntl(int fd, int cmd, ...) + __attribute__(( argument_with_type_tag(fcntl,3,2) )); + + +pointer_with_type_tag +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))`` +on a function declaration to specify that the function accepts a type tag that +determines the pointee type of some other pointer argument. + +For example: + +.. code-block:: c++ + + int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) + __attribute__(( pointer_with_type_tag(mpi,1,3) )); + + +type_tag_for_datatype +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","","","", "" + +Clang supports annotating type tags of two forms. + +* **Type tag that is an expression containing a reference to some declared + identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a + declaration with that identifier: + + .. code-block:: c++ + + extern struct mpi_datatype mpi_datatype_int + __attribute__(( type_tag_for_datatype(mpi,int) )); + #define MPI_INT ((MPI_Datatype) &mpi_datatype_int) + +* **Type tag that is an integral literal.** Introduce a ``static const`` + variable with a corresponding initializer value and attach + ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration, + for example: + + .. code-block:: c++ + + #define MPI_INT ((MPI_Datatype) 42) + static const MPI_Datatype mpi_datatype_int + __attribute__(( type_tag_for_datatype(mpi,int) )) = 42 + +The attribute also accepts an optional third argument that determines how the +expression is compared to the type tag. There are two supported flags: + +* ``layout_compatible`` will cause types to be compared according to + layout-compatibility rules (C++11 [class.mem] p 17, 18). This is + implemented to support annotating types like ``MPI_DOUBLE_INT``. + + For example: + + .. code-block:: c++ + + /* In mpi.h */ + struct internal_mpi_double_int { double d; int i; }; + extern struct mpi_datatype mpi_datatype_double_int + __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) )); + + #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int) + + /* In user code */ + struct my_pair { double a; int b; }; + struct my_pair *buffer; + MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning + + struct my_int_pair { int a; int b; } + struct my_int_pair *buffer2; + MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element + // type 'struct my_int_pair' + // doesn't match specified MPI_Datatype + +* ``must_be_null`` specifies that the expression should be a null pointer + constant, for example: + + .. code-block:: c++ + + /* In mpi.h */ + extern struct mpi_datatype mpi_datatype_null + __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); + + #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null) + + /* In user code */ + MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL + // was specified but buffer + // is not a null pointer + + +OpenCL Address Spaces +===================== +The address space qualifier may be used to specify the region of memory that is +used to allocate the object. OpenCL supports the following address spaces: +__generic(generic), __global(global), __local(local), __private(private), +__constant(constant). + + .. code-block:: c + + __constant int c = ...; + + __generic int* foo(global int* g) { + __local int* l; + private int p; + ... + return l; + } + +More details can be found in the OpenCL C language Spec v2.0, Section 6.5. + +constant (__constant) +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The constant address space attribute signals that an object is located in +a constant (non-modifiable) memory region. It is available to all work items. +Any type can be annotated with the constant address space attribute. Objects +with the constant address space qualifier can be declared in any scope and must +have an initializer. + + +generic (__generic) +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The generic address space attribute is only available with OpenCL v2.0 and later. +It can be used with pointer types. Variables in global and local scope and +function parameters in non-kernel functions can have the generic address space +type attribute. It is intended to be a placeholder for any other address space +except for '__constant' in OpenCL code which can be used with multiple address +spaces. + + +global (__global) +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The global address space attribute specifies that an object is allocated in +global memory, which is accessible by all work items. The content stored in this +memory area persists between kernel executions. Pointer types to the global +address space are allowed as function parameters or local variables. Starting +with OpenCL v2.0, the global address space can be used with global (program +scope) variables and static local variable as well. + + +local (__local) +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The local address space specifies that an object is allocated in the local (work +group) memory area, which is accessible to all work items in the same work +group. The content stored in this memory region is not accessible after +the kernel execution ends. In a kernel function scope, any variable can be in +the local address space. In other scopes, only pointer types to the local address +space are allowed. Local address space variables cannot have an initializer. + + +private (__private) +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The private address space specifies that an object is allocated in the private +(work item) memory. Other work items cannot access the same memory area and its +content is destroyed after work item execution ends. Local variables can be +declared in the private address space. Function arguments are always in the +private address space. Kernel function arguments of a pointer or an array type +cannot point to the private address space. + + +Nullability Attributes +====================== +Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``). + +The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example: + + .. code-block:: c + + // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior). + int fetch(int * _Nonnull ptr) { return *ptr; } + + // 'ptr' may be null. + int fetch_or_zero(int * _Nullable ptr) { + return ptr ? *ptr : 0; + } + + // A nullable pointer to non-null pointers to const characters. + const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n); + +In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example: + + .. code-block:: objective-c + + @interface NSView : NSResponder + - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView; + @property (assign, nullable) NSView *superview; + @property (readonly, nonnull) NSArray *subviews; + @end + +nonnull (gnu::nonnull) +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC `_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example: + + .. code-block:: c + + extern void * my_memcpy (void *dest, const void *src, size_t len) + __attribute__((nonnull (1, 2))); + +Here, the ``nonnull`` attribute indicates that parameters 1 and 2 +cannot have a null value. Omitting the parenthesized list of parameter indices means that all parameters of pointer type cannot be null: + + .. code-block:: c + + extern void * my_memcpy (void *dest, const void *src, size_t len) + __attribute__((nonnull)); + +Clang also allows the ``nonnull`` attribute to be placed directly on a function (or Objective-C method) parameter, eliminating the need to specify the parameter index ahead of type. For example: + + .. code-block:: c + + extern void * my_memcpy (void *dest __attribute__((nonnull)), + const void *src __attribute__((nonnull)), size_t len); + +Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable. + + +returns_nonnull (gnu::returns_nonnull) +-------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "X","X","","", "" + +The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer: + + .. code-block:: c + + extern void * malloc (size_t size) __attribute__((returns_nonnull)); + +The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable + + +_Nonnull +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as: + + .. code-block:: c + + int fetch(int * _Nonnull ptr); + +a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null. + + +_Null_unspecified +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API. + + +_Nullable +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" + + "","","","X", "" + +The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given: + + .. code-block:: c + + int fetch_or_zero(int * _Nullable ptr); + +a caller of ``fetch_or_zero`` can provide null. + + diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index f42439a9bf1..13b79fdfa53 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -95,6 +95,10 @@ if (LLVM_ENABLE_SPHINX) include(AddSphinxTarget) if (${SPHINX_OUTPUT_HTML}) add_sphinx_target(html clang) + add_custom_command(TARGET docs-clang-html POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/LibASTMatchersReference.html" + "${CMAKE_CURRENT_BINARY_DIR}/html/LibASTMatchersReference.html") endif() if (${SPHINX_OUTPUT_MAN}) add_sphinx_target(man clang) diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst index b4968ef1036..3f52b767e3a 100644 --- a/docs/ClangFormat.rst +++ b/docs/ClangFormat.rst @@ -190,7 +190,7 @@ In an SVN client, you can do: .. code-block:: console - svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i + svn diff --diff-cmd=diff -x -U0 | clang-format-diff.py -i -The :option:`-U0` will create a diff without context lines (the script would format +The option `-U0` will create a diff without context lines (the script would format those as well). diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index bfabd5985ca..a548e835a56 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -154,7 +154,7 @@ the configuration (without a prefix: ``Auto``). If ``true``, horizontally aligns arguments after an open bracket. This applies to round brackets (parentheses), angle brackets and square - brackets. This will result in formattings like + brackets. Possible values: @@ -165,6 +165,7 @@ the configuration (without a prefix: ``Auto``). someLongFunction(argument1, argument2); + * ``BAS_DontAlign`` (in configuration: ``DontAlign``) Don't align, instead use ``ContinuationIndentWidth``, e.g.: @@ -172,6 +173,7 @@ the configuration (without a prefix: ``Auto``). someLongFunction(argument1, argument2); + * ``BAS_AlwaysBreak`` (in configuration: ``AlwaysBreak``) Always break after an open bracket, if the parameters don't fit on a single line, e.g.: @@ -182,6 +184,7 @@ the configuration (without a prefix: ``Auto``). argument1, argument2); + **AlignConsecutiveAssignments** (``bool``) If ``true``, aligns consecutive assignments. @@ -214,6 +217,14 @@ the configuration (without a prefix: ``Auto``). 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.: + + .. code-block:: c++ + + int aaa = bbbbbbbbbbbbbbb + + ccccccccccccccc; + **AlignTrailingComments** (``bool``) If ``true``, aligns trailing comments. @@ -230,28 +241,31 @@ the configuration (without a prefix: ``Auto``). If ``true``, short case labels will be contracted to a single line. **AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``) - Dependent on the value, ``int f() { return 0; }`` can be put - on a single line. + Dependent on the value, ``int f() { return 0; }`` can be put on a + single line. Possible values: * ``SFS_None`` (in configuration: ``None``) Never merge functions into a single line. + * ``SFS_Empty`` (in configuration: ``Empty``) Only merge empty functions. + * ``SFS_Inline`` (in configuration: ``Inline``) Only merge functions defined inside a class. Implies "empty". + * ``SFS_All`` (in configuration: ``All``) Merge all functions fitting on a single line. + **AllowShortIfStatementsOnASingleLine** (``bool``) - If ``true``, ``if (a) return;`` can be put on a single - line. + If ``true``, ``if (a) return;`` can be put on a single line. **AllowShortLoopsOnASingleLine** (``bool``) - If ``true``, ``while (true) continue;`` can be put on a - single line. + If ``true``, ``while (true) continue;`` can be put on a single + line. **AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``) The function definition return type breaking style to use. This @@ -262,12 +276,15 @@ the configuration (without a prefix: ``Auto``). * ``DRTBS_None`` (in configuration: ``None``) Break after return type automatically. ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. + * ``DRTBS_All`` (in configuration: ``All``) Always break after the return type. + * ``DRTBS_TopLevel`` (in configuration: ``TopLevel``) Always break after the return types of top-level functions. + **AlwaysBreakAfterReturnType** (``ReturnTypeBreakingStyle``) The function declaration return type breaking style to use. @@ -276,16 +293,21 @@ the configuration (without a prefix: ``Auto``). * ``RTBS_None`` (in configuration: ``None``) Break after return type automatically. ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. + * ``RTBS_All`` (in configuration: ``All``) Always break after the return type. + * ``RTBS_TopLevel`` (in configuration: ``TopLevel``) Always break after the return types of top-level functions. + * ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``) Always break after the return type of function definitions. + * ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``) Always break after the return type of top-level definitions. + **AlwaysBreakBeforeMultilineStrings** (``bool``) If ``true``, always break before multiline string literals. @@ -295,8 +317,8 @@ the configuration (without a prefix: ``Auto``). ``ContinuationIndentWidth`` spaces from the start of the line. **AlwaysBreakTemplateDeclarations** (``bool``) - If ``true``, always break after the ``template<...>`` of a - template declaration. + If ``true``, always break after the ``template<...>`` of a template + declaration. **BinPackArguments** (``bool``) If ``false``, a function call's arguments will either be all on the @@ -309,17 +331,17 @@ the configuration (without a prefix: ``Auto``). **BraceWrapping** (``BraceWrappingFlags``) Control of individual brace wrapping cases. - If ``BreakBeforeBraces`` is set to ``custom``, use this to specify how each - individual brace case should be handled. Otherwise, this is ignored. + If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how + each individual brace case should be handled. Otherwise, this is ignored. Nested configuration flags: * ``bool AfterClass`` Wrap class definitions. - * ``bool AfterControlStatement`` Wrap control statements (if/for/while/switch/..). + * ``bool AfterControlStatement`` Wrap control statements (``if``/``for``/``while``/``switch``/..). * ``bool AfterEnum`` Wrap enum definitions. * ``bool AfterFunction`` Wrap function definitions. * ``bool AfterNamespace`` Wrap namespace definitions. - * ``bool AfterObjCDeclaration`` Wrap ObjC definitions (@autoreleasepool, interfaces, ..). + * ``bool AfterObjCDeclaration`` Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..). * ``bool AfterStruct`` Wrap struct definitions. * ``bool AfterUnion`` Wrap union definitions. * ``bool BeforeCatch`` Wrap before ``catch``. @@ -337,12 +359,15 @@ the configuration (without a prefix: ``Auto``). * ``BOS_None`` (in configuration: ``None``) Break after operators. + * ``BOS_NonAssignment`` (in configuration: ``NonAssignment``) Break before operators that aren't assignments. + * ``BOS_All`` (in configuration: ``All``) Break before operators. + **BreakBeforeBraces** (``BraceBreakingStyle``) The brace breaking style to use. @@ -350,24 +375,33 @@ the configuration (without a prefix: ``Auto``). * ``BS_Attach`` (in configuration: ``Attach``) Always attach braces to surrounding context. + * ``BS_Linux`` (in configuration: ``Linux``) Like ``Attach``, but break before braces on function, namespace and class definitions. + * ``BS_Mozilla`` (in configuration: ``Mozilla``) Like ``Attach``, but break before braces on enum, function, and record definitions. + * ``BS_Stroustrup`` (in configuration: ``Stroustrup``) - Like ``Attach``, but break before function definitions, 'catch', and 'else'. + Like ``Attach``, but break before function definitions, ``catch``, and + ``else``. + * ``BS_Allman`` (in configuration: ``Allman``) Always break before braces. + * ``BS_GNU`` (in configuration: ``GNU``) Always break before braces and add an extra level of indentation to braces of control statements, not to those of class, function or other definitions. + * ``BS_WebKit`` (in configuration: ``WebKit``) Like ``Attach``, but break before functions. + * ``BS_Custom`` (in configuration: ``Custom``) - Configure each individual brace in ``BraceWrapping``. + Configure each individual brace in `BraceWrapping`. + **BreakBeforeTernaryOperators** (``bool``) @@ -377,6 +411,9 @@ the configuration (without a prefix: ``Auto``). Always break constructor initializers before commas and align the commas with the colon. +**BreakStringLiterals** (``bool``) + Allow breaking string literals when formatting. + **ColumnLimit** (``unsigned``) The column limit. @@ -416,7 +453,8 @@ the configuration (without a prefix: ``Auto``). **DerivePointerAlignment** (``bool``) If ``true``, analyze the formatted file for the most common - alignment of & and \*. ``PointerAlignment`` is then used only as fallback. + alignment of ``&`` and ``\*``. ``PointerAlignment`` is then used only as + fallback. **DisableFormat** (``bool``) Disables formatting completely. @@ -446,30 +484,32 @@ the configuration (without a prefix: ``Auto``). In the .clang-format configuration file, this can be configured like: - .. code-block:: c++ + .. code-block:: yaml ForEachMacros: ['RANGES_FOR', 'FOREACH'] For example: BOOST_FOREACH. **IncludeCategories** (``std::vector``) - Regular expressions denoting the different #include categories used - for ordering #includes. + Regular expressions denoting the different ``#include`` categories + used for ordering ``#includes``. These regular expressions are matched against the filename of an include (including the <> or "") in order. The value belonging to the first - matching regular expression is assigned and #includes are sorted first + matching regular expression is assigned and ``#includes`` are sorted first according to increasing category number and then alphabetically within each category. - If none of the regular expressions match, UINT_MAX is assigned as - category. The main header for a source file automatically gets category 0, - so that it is kept at the beginning of the #includes - (http://llvm.org/docs/CodingStandards.html#include-style). + If none of the regular expressions match, INT_MAX is assigned as + category. The main header for a source file automatically gets category 0. + so that it is generally kept at the beginning of the ``#includes`` + (http://llvm.org/docs/CodingStandards.html#include-style). However, you + can also assign negative priorities if you have certain headers that + always need to be first. To configure this in the .clang-format file, use: - .. code-block:: c++ + .. code-block:: yaml IncludeCategories: - Regex: '^"(llvm|llvm-c|clang|clang-c)/' @@ -479,6 +519,19 @@ the configuration (without a prefix: ``Auto``). - Regex: '.\*' Priority: 1 +**IncludeIsMainRegex** (``std::string``) + Specify a regular expression of suffixes that are allowed in the + file-to-main-include mapping. + + When guessing whether a #include is the "main" include (to assign + category 0, see above), use this regex of allowed suffixes to the header + stem. A partial match is done, so that: + - "" means "arbitrary suffix" + - "$" means "no suffix" + + For example, if configured to "(_test)?$", then a header a.h would be seen + as the "main" include in both a.cc and a_test.cc. + **IndentCaseLabels** (``bool``) Indent case labels one level from the switch statement. @@ -492,6 +545,22 @@ the configuration (without a prefix: ``Auto``). Indent if a function definition or declaration is wrapped after the type. +**JavaScriptQuotes** (``JavaScriptQuoteStyle``) + The JavaScriptQuoteStyle to use for JavaScript strings. + + Possible values: + + * ``JSQS_Leave`` (in configuration: ``Leave``) + Leave string quotes as they are. + + * ``JSQS_Single`` (in configuration: ``Single``) + Always use single quotes. + + * ``JSQS_Double`` (in configuration: ``Double``) + Always use double quotes. + + + **KeepEmptyLinesAtTheStartOfBlocks** (``bool``) If true, empty lines at the start of blocks are kept. @@ -502,16 +571,24 @@ the configuration (without a prefix: ``Auto``). * ``LK_None`` (in configuration: ``None``) Do not use. + * ``LK_Cpp`` (in configuration: ``Cpp``) Should be used for C, C++, ObjectiveC, ObjectiveC++. + * ``LK_Java`` (in configuration: ``Java``) Should be used for Java. + * ``LK_JavaScript`` (in configuration: ``JavaScript``) Should be used for JavaScript. + * ``LK_Proto`` (in configuration: ``Proto``) Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/). + * ``LK_TableGen`` (in configuration: ``TableGen``) + Should be used for TableGen code. + + **MacroBlockBegin** (``std::string``) A regular expression matching macros that start a block. @@ -529,25 +606,28 @@ the configuration (without a prefix: ``Auto``). * ``NI_None`` (in configuration: ``None``) Don't indent in namespaces. + * ``NI_Inner`` (in configuration: ``Inner``) Indent only in inner namespaces (nested in other namespaces). + * ``NI_All`` (in configuration: ``All``) Indent in all namespaces. + **ObjCBlockIndentWidth** (``unsigned``) The number of characters to use for indentation of ObjC blocks. **ObjCSpaceAfterProperty** (``bool``) Add a space after ``@property`` in Objective-C, i.e. use - ``\@property (readonly)`` instead of ``\@property(readonly)``. + ``@property (readonly)`` instead of ``@property(readonly)``. **ObjCSpaceBeforeProtocolList** (``bool``) Add a space in front of an Objective-C protocol list, i.e. use ``Foo `` instead of ``Foo``. **PenaltyBreakBeforeFirstCallParameter** (``unsigned``) - The penalty for breaking a function call after "call(". + The penalty for breaking a function call after ``call(``. **PenaltyBreakComment** (``unsigned``) The penalty for each line break introduced inside a comment. @@ -572,12 +652,21 @@ the configuration (without a prefix: ``Auto``). * ``PAS_Left`` (in configuration: ``Left``) Align pointer to the left. + * ``PAS_Right`` (in configuration: ``Right``) Align pointer to the right. + * ``PAS_Middle`` (in configuration: ``Middle``) Align pointer in the middle. + +**ReflowComments** (``bool``) + If ``true``, clang-format will attempt to re-flow comments. + +**SortIncludes** (``bool``) + If ``true``, clang-format will sort ``#includes``. + **SpaceAfterCStyleCast** (``bool``) If ``true``, a space may be inserted after C style casts. @@ -591,9 +680,11 @@ the configuration (without a prefix: ``Auto``). * ``SBPO_Never`` (in configuration: ``Never``) Never put a space before opening parentheses. + * ``SBPO_ControlStatements`` (in configuration: ``ControlStatements``) Put a space before opening parentheses only after control statement keywords (``for/if/while...``). + * ``SBPO_Always`` (in configuration: ``Always``) Always put a space before opening parentheses, except when it's prohibited by the syntax rules (in function-like macro definitions) or @@ -601,19 +692,21 @@ the configuration (without a prefix: ``Auto``). parentheses, etc.) + **SpaceInEmptyParentheses** (``bool``) - If ``true``, spaces may be inserted into '()'. + If ``true``, spaces may be inserted into ``()``. **SpacesBeforeTrailingComments** (``unsigned``) The number of spaces before trailing line comments (``//`` - comments). - This does not affect trailing block comments (``/**/`` - comments) as those - commonly have different usage patterns and a number of special cases. + This does not affect trailing block comments (``/*`` - comments) as + those commonly have different usage patterns and a number of special + cases. **SpacesInAngles** (``bool``) - If ``true``, spaces will be inserted after '<' and before '>' in - template argument lists + If ``true``, spaces will be inserted after ``<`` and before ``>`` + in template argument lists. **SpacesInCStyleCastParentheses** (``bool``) If ``true``, spaces may be inserted into C style casts. @@ -623,26 +716,28 @@ the configuration (without a prefix: ``Auto``). ObjC and Javascript array and dict literals). **SpacesInParentheses** (``bool``) - If ``true``, spaces will be inserted after '(' and before ')'. + If ``true``, spaces will be inserted after ``(`` and before ``)``. **SpacesInSquareBrackets** (``bool``) - If ``true``, spaces will be inserted after '[' and before ']'. + If ``true``, spaces will be inserted after ``[`` and before ``]``. **Standard** (``LanguageStandard``) - Format compatible with this standard, e.g. use - ``A >`` instead of ``A>`` for LS_Cpp03. + Format compatible with this standard, e.g. use ``A >`` + instead of ``A>`` for ``LS_Cpp03``. Possible values: * ``LS_Cpp03`` (in configuration: ``Cpp03``) Use C++03-compatible syntax. + * ``LS_Cpp11`` (in configuration: ``Cpp11``) - Use features of C++11 (e.g. ``A>`` instead of - ``A >``). + Use features of C++11 (e.g. ``A>`` instead of ``A >``). + * ``LS_Auto`` (in configuration: ``Auto``) Automatic detection based on the input. + **TabWidth** (``unsigned``) The number of columns used for tab stops. @@ -653,20 +748,23 @@ the configuration (without a prefix: ``Auto``). * ``UT_Never`` (in configuration: ``Never``) Never use tab. + * ``UT_ForIndentation`` (in configuration: ``ForIndentation``) Use tabs only for indentation. + * ``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. + .. END_FORMAT_STYLE_OPTIONS Adding additional style options =============================== Each additional style option adds costs to the clang-format project. Some of -these costs affect the clang-format developement itself, as we need to make +these costs affect the clang-format development itself, as we need to make sure that any given combination of options work and that new features don't break any of the existing options in any way. There are also costs for end users as options become less discoverable and people have to think about and make a diff --git a/docs/ClangPlugins.rst b/docs/ClangPlugins.rst index 9a5bc142130..833f0dd39f7 100644 --- a/docs/ClangPlugins.rst +++ b/docs/ClangPlugins.rst @@ -43,6 +43,26 @@ register a plugin in a library, use ``FrontendPluginRegistry::Add<>``: static FrontendPluginRegistry::Add X("my-plugin-name", "my plugin description"); +Defining pragmas +================ + +Plugins can also define pragmas by declaring a ``PragmaHandler`` and +registering it using ``PragmaHandlerRegistry::Add<>``: + +.. code-block:: c++ + + // Define a pragma handler for #pragma example_pragma + class ExamplePragmaHandler : public PragmaHandler { + public: + ExamplePragmaHandler() : PragmaHandler("example_pragma") { } + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &PragmaTok) { + // Handle the pragma + } + }; + + static PragmaHandlerRegistry::Add Y("example_pragma","example pragma description"); + Putting it all together ======================= @@ -54,21 +74,25 @@ the `latest version of PrintFunctionNames.cpp Running the plugin ================== + +Using the cc1 command line +-------------------------- + To run a plugin, the dynamic library containing the plugin registry must be -loaded via the :option:`-load` command line option. This will load all plugins +loaded via the `-load` command line option. This will load all plugins that are registered, and you can select the plugins to run by specifying the -:option:`-plugin` option. Additional parameters for the plugins can be passed with -:option:`-plugin-arg-`. +`-plugin` option. Additional parameters for the plugins can be passed with +`-plugin-arg-`. Note that those options must reach clang's cc1 process. There are two ways to do so: -* Directly call the parsing process by using the :option:`-cc1` option; this +* Directly call the parsing process by using the `-cc1` option; this has the downside of not configuring the default header search paths, so you'll need to specify the full system path configuration on the command line. * Use clang as usual, but prefix all arguments to the cc1 process with - :option:`-Xclang`. + `-Xclang`. For example, to run the ``print-function-names`` plugin over a source file in clang, first build the plugin, and then call clang with the plugin from the @@ -88,3 +112,19 @@ source tree: Also see the print-function-name plugin example's `README `_ + +Using the clang command line +---------------------------- + +Using `-fplugin=plugin` on the clang command line passes the plugin +through as an argument to `-load` on the cc1 command line. If the plugin +class implements the ``getActionType`` method then the plugin is run +automatically. For example, to run the plugin automatically after the main AST +action (i.e. the same as using `-add-plugin`): + +.. code-block:: c++ + + // Automatically run the plugin after the main AST action + PluginASTAction::ActionType getActionType() override { + return AddAfterMainAction; + } diff --git a/docs/CommandGuide/clang.rst b/docs/CommandGuide/clang.rst index 2b4569592a9..0546304e710 100644 --- a/docs/CommandGuide/clang.rst +++ b/docs/CommandGuide/clang.rst @@ -184,7 +184,7 @@ Language Selection and Mode Options (either via :option:`-fobjc-nonfragile-abi`, or because it is the platform default). -.. option:: -fobjc-nonfragile-abi +.. option:: -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi Enable use of the Objective-C non-fragile ABI. On platforms for which this is the default ABI, it can be disabled with :option:`-fno-objc-nonfragile-abi`. @@ -253,22 +253,32 @@ Code Generation Options Currently equivalent to :option:`-O3` -.. option:: -g +.. option:: -g, -gline-tables-only, -gmodules - Generate debug information. Note that Clang debug information works best at -O0. + Control debug information output. Note that Clang debug information works + best at :option:`-O0`. When more than one option starting with `-g` is + specified, the last one wins: -.. option:: -gmodules + :option:`-g` Generate debug information. - Generate debug information that contains external references to - types defined in clang modules or precompiled headers instead of - emitting redundant debug type information into every object file. - This option implies :option:`-fmodule-format=obj`. + :option:`-gline-tables-only` Generate only line table debug information. This + allows for symbolicated backtraces with inlining information, but does not + include any information about variables, their locations or types. + + :option:`-gmodules` Generate debug information that contains external + references to types defined in Clang modules or precompiled headers instead + of emitting redundant debug type information into every object file. This + option transparently switches the Clang module format to object file + containers that hold the Clang module together with the debug information. + When compiling a program that uses Clang modules or precompiled headers, + this option produces complete debug information with faster compile + times and much smaller object files. + + This option should not be used when building static libraries for + distribution to other machines because the debug info will contain + references to the module cache on the machine the object files in the + library were built on. - This option should not be used when building static libraries for - distribution to other machines because the debug info will contain - references to the module cache on the machine the object files in - the library were built on. - .. option:: -fstandalone-debug -fno-standalone-debug Clang supports a number of optimizations to reduce the size of debug @@ -300,7 +310,7 @@ Code Generation Options This flag sets the default visibility level. -.. option:: -fcommon +.. option:: -fcommon, -fno-common This flag specifies that variables without initializers get common linkage. It can be disabled with :option:`-fno-common`. diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst index 780ff882d0e..eed5ac51200 100644 --- a/docs/ControlFlowIntegrity.rst +++ b/docs/ControlFlowIntegrity.rst @@ -25,13 +25,25 @@ As currently implemented, all schemes rely on link-time optimization (LTO); so it is required to specify ``-flto``, and the linker used must support LTO, for example via the `gold plugin`_. -To allow the checks to be implemented efficiently, the program must be -structured such that certain object files are compiled with CFI +To allow the checks to be implemented efficiently, the program must +be structured such that certain object files are compiled with CFI enabled, and are statically linked into the program. This may preclude -the use of shared libraries in some cases. Experimental support for -:ref:`cross-DSO control flow integrity ` exists that -does not have these requirements. This cross-DSO support has unstable -ABI at this time. +the use of shared libraries in some cases. + +The compiler will only produce CFI checks for a class if it can infer hidden +LTO visibility for that class. LTO visibility is a property of a class that +is inferred from flags and attributes. For more details, see the documentation +for :doc:`LTO visibility `. + +The ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags +require that a ``-fvisibility=`` flag also be specified. This is because the +default visibility setting is ``-fvisibility=default``, which would disable +CFI checks for classes without visibility attributes. Most users will want +to specify ``-fvisibility=hidden``, which enables CFI checks for such classes. + +Experimental support for :ref:`cross-DSO control flow integrity +` exists that does not require classes to have hidden LTO +visibility. This cross-DSO support has unstable ABI at this time. .. _gold plugin: http://llvm.org/docs/GoldPlugin.html @@ -129,7 +141,8 @@ type ``void*`` or another unrelated type (which can be checked with The difference between these two types of casts is that the first is defined by the C++ standard to produce an undefined value, while the second is not in itself undefined behavior (it is well defined to cast the pointer back -to its original type). +to its original type) unless the object is uninitialized and the cast is a +``static_cast`` (see C++14 [basic.life]p5). If a program as a matter of policy forbids the second type of cast, that restriction can normally be enforced. However it may in some cases be necessary @@ -232,11 +245,6 @@ A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain source files, functions and types using the ``src``, ``fun`` and ``type`` entity types. -In addition, if a type has a ``uuid`` attribute and the blacklist contains -the type entry ``attr:uuid``, CFI checks are suppressed for that type. This -allows all COM types to be easily blacklisted, which is useful as COM types -are typically defined outside of the linked program. - .. code-block:: bash # Suppress checking for code in a file. @@ -246,8 +254,6 @@ are typically defined outside of the linked program. fun:*MyFooBar* # Ignore all types in the standard library. type:std::* - # Ignore all types with a uuid attribute. - type:attr:uuid .. _cfi-cross-dso: @@ -259,6 +265,11 @@ flow integrity mode, which allows all CFI schemes listed above to apply across DSO boundaries. As in the regular CFI, each DSO must be built with ``-flto``. +Normally, CFI checks will only be performed for classes that have hidden LTO +visibility. With this flag enabled, the compiler will emit cross-DSO CFI +checks for all classes, except for those which appear in the CFI blacklist +or which use a ``no_sanitize`` attribute. + Design ====== diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst index b4aacd36567..38c5e5b99e3 100644 --- a/docs/ControlFlowIntegrityDesign.rst +++ b/docs/ControlFlowIntegrityDesign.rst @@ -90,10 +90,10 @@ For example on x86 a typical virtual call may look like this: The compiler relies on co-operation from the linker in order to assemble the bit vectors for the whole program. It currently does this using LLVM's -`bit sets`_ mechanism together with link-time optimization. +`type metadata`_ mechanism together with link-time optimization. .. _address point: https://mentorembedded.github.io/cxx-abi/abi.html#vtable-general -.. _bit sets: http://llvm.org/docs/BitSets.html +.. _type metadata: http://llvm.org/docs/TypeMetadata.html .. _ByteArrayBuilder: http://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html Optimizations @@ -196,7 +196,7 @@ those sub-hierarchies need to be (see "Stripping Leading/Trailing Zeros in Bit Vectors" above). The `GlobalLayoutBuilder`_ class is responsible for laying out the globals efficiently to minimize the sizes of the underlying bitsets. -.. _GlobalLayoutBuilder: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/LowerBitSets.h?view=markup +.. _GlobalLayoutBuilder: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/LowerTypeTests.h?view=markup Alignment ~~~~~~~~~ @@ -297,8 +297,8 @@ file's symbol table, the symbols for the target functions also refer to the jump table entries, so that addresses taken outside the module will pass any verification done inside the module. -In more concrete terms, suppose we have three functions ``f``, ``g``, ``h`` -which are members of a single bitset, and a function foo that returns their +In more concrete terms, suppose we have three functions ``f``, ``g``, +``h`` which are all of the same type, and a function foo that returns their addresses: .. code-block:: none @@ -439,10 +439,10 @@ export this information, every DSO implements void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr) -This function provides external modules with access to CFI checks for -the targets inside this DSO. For each known ``CallSiteTypeId``, this -functions performs an ``llvm.bitset.test`` with the corresponding bit -set. It aborts if the type is unknown, or if the check fails. +This function provides external modules with access to CFI checks for the +targets inside this DSO. For each known ``CallSiteTypeId``, this function +performs an ``llvm.type.test`` with the corresponding type identifier. It +aborts if the type is unknown, or if the check fails. The basic implementation is a large switch statement over all values of CallSiteTypeId supported by this DSO, and each case is similar to diff --git a/docs/CrossCompilation.rst b/docs/CrossCompilation.rst index 8a802711737..c07bc21a430 100644 --- a/docs/CrossCompilation.rst +++ b/docs/CrossCompilation.rst @@ -32,7 +32,7 @@ when compiling your code. On the other hand, Clang/LLVM is natively a cross-compiler, meaning that one set of programs can compile to all targets by setting the ``-target`` -option. That makes it a lot easier for programers wishing to compile to +option. That makes it a lot easier for programmers wishing to compile to different platforms and architectures, and for compiler developers that only have to maintain one build system, and for OS distributions, that need only one set of main packages. diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst index c4af5b112ac..dc89d123c0e 100644 --- a/docs/InternalsManual.rst +++ b/docs/InternalsManual.rst @@ -57,7 +57,7 @@ driver, but diagnostics can be :ref:`rendered in many different ways ` depending on how the ``DiagnosticClient`` interface is implemented. A representative example of a diagnostic is: -.. code-block:: c++ +.. code-block:: text t.c:38:15: error: invalid operands to binary expression ('int *' and '_Complex float') P = (P-42) + Gamma*4; @@ -374,7 +374,7 @@ use of a deprecated construct into something more palatable. Here is one such example from the C++ front end, where we warn about the right-shift operator changing meaning from C++98 to C++11: -.. code-block:: c++ +.. code-block:: text test.cpp:3:7: warning: use of right-shift operator ('>>') in template argument will require parentheses in C++11 @@ -514,7 +514,7 @@ Clang represents most source ranges by [first, last], where "first" and "last" each point to the beginning of their respective tokens. For example consider the ``SourceRange`` of the following statement: -.. code-block:: c++ +.. code-block:: text x = foo + bar; ^first ^last @@ -837,7 +837,7 @@ typedefs. For example, consider this code: The code above is illegal, and thus we expect there to be diagnostics emitted on the annotated lines. In this example, we expect to get: -.. code-block:: c++ +.. code-block:: text test.c:6:1: error: indirection requires pointer operand ('foo' invalid) *X; // error @@ -1422,7 +1422,7 @@ pretty-printed version of the CFG to standard error. This is especially useful when one is using a debugger such as gdb. For example, here is the output of ``FooCFG->dump()``: -.. code-block:: c++ +.. code-block:: text [ B5 (ENTRY) ] Predecessors (0): diff --git a/docs/ItaniumMangleAbiTags.rst b/docs/ItaniumMangleAbiTags.rst new file mode 100644 index 00000000000..2d65031b70e --- /dev/null +++ b/docs/ItaniumMangleAbiTags.rst @@ -0,0 +1,107 @@ +======== +ABI tags +======== + +Introduction +============ + +This text tries to describe gcc semantic for mangling "abi_tag" attributes +described in https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html + +There is no guarantee the following rules are correct, complete or make sense +in any way as they were determined empirically by experiments with gcc5. + +Declaration +=========== + +ABI tags are declared in an abi_tag attribute and can be applied to a +function, variable, class or inline namespace declaration. The attribute takes +one or more strings (called tags); the order does not matter. + +See https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html for +details. + +Tags on an inline namespace are called "implicit tags", all other tags are +"explicit tags". + +Mangling +======== + +All tags that are "active" on an are emitted after the +, before or , and are part of +the same the is. + +They are mangled as: + +.. code-block:: none + + ::= * # sort by name + ::= B + +Example: + +.. code-block:: c++ + + __attribute__((abi_tag("test"))) + void Func(); + // gets mangled as: _Z4FuncB4testv (prettified as `Func[abi:test]()`) + +Active tags +=========== + +A namespace does not have any active tags. For types (class / struct / union / +enum), the explicit tags are the active tags. + +For variables and functions, the active tags are the explicit tags plus any +"required tags" which are not in the "available tags" set: + +.. code-block:: none + + derived-tags := (required-tags - available-tags) + active-tags := explicit-tags + derived-tags + +Required tags for a function +============================ + +If a function is used as a local scope for another name, and is part of +another function as local scope, it doesn't have any required tags. + +If a function is used as a local scope for a guard variable name, it doesn't +have any required tags. + +Otherwise the function requires any implicit or explicit tag used in the name +for the return type. + +Example: + +.. code-block:: c++ + + namespace A { + inline namespace B __attribute__((abi_tag)) { + struct C { int x; }; + } + } + + A::C foo(); // gets mangled as: _Z3fooB1Bv (prettified as `foo[abi:B]()`) + +Required tags for a variable +============================ + +A variable requires any implicit or explicit tag used in its type. + +Available tags +============== + +All tags used in the prefix and in the template arguments for a name are +available. Also, for functions, all tags from the +(which might include the return type for template functions) are available. + +For s all active tags used in the local part () are available, but not implicit tags which were not active. + +Implicit and explicit tags used in the for a function (as +in the type of a cast operator) are NOT available. + +Example: a cast operator to std::string (which is +std::__cxx11::basic_string<...>) will use 'cxx11' as an active tag, as it is +required from the return type `std::string` but not available. diff --git a/docs/LTOVisibility.rst b/docs/LTOVisibility.rst new file mode 100644 index 00000000000..67367f3d635 --- /dev/null +++ b/docs/LTOVisibility.rst @@ -0,0 +1,113 @@ +============== +LTO Visibility +============== + +*LTO visibility* is a property of an entity that specifies whether it can be +referenced from outside the current LTO unit. A *linkage unit* is a set of +translation units linked together into an executable or DSO, and a linkage +unit's *LTO unit* is the subset of the linkage unit that is linked together +using link-time optimization; in the case where LTO is not being used, the +linkage unit's LTO unit is empty. Each linkage unit has only a single LTO unit. + +The LTO visibility of a class is used by the compiler to determine which +classes the virtual function call optimization and control flow integrity +features apply to. These features use whole-program information, so they +require the entire class hierarchy to be visible in order to work correctly. + +If any translation unit in the program uses either of the virtual function +call optimization or control flow integrity features, it is effectively an +ODR violation to define a class with hidden LTO visibility in multiple linkage +units. A class with public LTO visibility may be defined in multiple linkage +units, but the tradeoff is that the virtual function call optimization and +control flow integrity features can only be applied to classes with hidden LTO +visibility. A class's LTO visibility is treated as an ODR-relevant property +of its definition, so it must be consistent between translation units. + +In translation units built with LTO, LTO visibility is based on the +class's symbol visibility as expressed at the source level (i.e. the +``__attribute__((visibility("...")))`` attribute, or the ``-fvisibility=`` +flag) or, on the Windows platform, the dllimport and dllexport attributes. When +targeting non-Windows platforms, classes with a visibility other than hidden +visibility receive public LTO visibility. When targeting Windows, classes +with dllimport or dllexport attributes receive public LTO visibility. All +other classes receive hidden LTO visibility. Classes with internal linkage +(e.g. classes declared in unnamed namespaces) also receive hidden LTO +visibility. + +A class defined in a translation unit built without LTO receives public +LTO visibility regardless of its object file visibility, linkage or other +attributes. + +This mechanism will produce the correct result in most cases, but there are +two cases where it may wrongly infer hidden LTO visibility. + +1. As a corollary of the above rules, if a linkage unit is produced from a + combination of LTO object files and non-LTO object files, any hidden + visibility class defined in both a translation unit built with LTO and + a translation unit built without LTO must be defined with public LTO + visibility in order to avoid an ODR violation. + +2. Some ABIs provide the ability to define an abstract base class without + visibility attributes in multiple linkage units and have virtual calls + to derived classes in other linkage units work correctly. One example of + this is COM on Windows platforms. If the ABI allows this, any base class + used in this way must be defined with public LTO visibility. + +Classes that fall into either of these categories can be marked up with the +``[[clang::lto_visibility_public]]`` attribute. To specifically handle the +COM case, classes with the ``__declspec(uuid())`` attribute receive public +LTO visibility. On Windows platforms, clang-cl's ``/MT`` and ``/MTd`` +flags statically link the program against a prebuilt standard library; +these flags imply public LTO visibility for every class declared in the +``std`` and ``stdext`` namespaces. + +Example +======= + +The following example shows how LTO visibility works in practice in several +cases involving two linkage units, ``main`` and ``dso.so``. + +.. code-block:: none + + +-----------------------------------------------------------+ +----------------------------------------------------+ + | main (clang++ -fvisibility=hidden): | | dso.so (clang++ -fvisibility=hidden): | + | | | | + | +-----------------------------------------------------+ | | struct __attribute__((visibility("default"))) C { | + | | LTO unit (clang++ -fvisibility=hidden -flto): | | | virtual void f(); | + | | | | | } | + | | struct A { ... }; | | | void C::f() {} | + | | struct [[clang::lto_visibility_public]] B { ... }; | | | struct D { | + | | struct __attribute__((visibility("default"))) C { | | | virtual void g() = 0; | + | | virtual void f(); | | | }; | + | | }; | | | struct E : D { | + | | struct [[clang::lto_visibility_public]] D { | | | virtual void g() { ... } | + | | virtual void g() = 0; | | | }; | + | | }; | | | __attribute__(visibility("default"))) D *mkE() { | + | | | | | return new E; | + | +-----------------------------------------------------+ | | } | + | | | | + | struct B { ... }; | +----------------------------------------------------+ + | | + +-----------------------------------------------------------+ + +We will now describe the LTO visibility of each of the classes defined in +these linkage units. + +Class ``A`` is not defined outside of ``main``'s LTO unit, so it can have +hidden LTO visibility. This is inferred from the object file visibility +specified on the command line. + +Class ``B`` is defined in ``main``, both inside and outside its LTO unit. The +definition outside the LTO unit has public LTO visibility, so the definition +inside the LTO unit must also have public LTO visibility in order to avoid +an ODR violation. + +Class ``C`` is defined in both ``main`` and ``dso.so`` and therefore must +have public LTO visibility. This is correctly inferred from the ``visibility`` +attribute. + +Class ``D`` is an abstract base class with a derived class ``E`` defined +in ``dso.so``. This is an example of the COM scenario; the definition of +``D`` in ``main``'s LTO unit must have public LTO visibility in order to be +compatible with the definition of ``D`` in ``dso.so``, which is observable +by calling the function ``mkE``. diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 333dee618ce..51ac3ab1a8c 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -449,7 +449,7 @@ An optional string message can be added to the ``deprecated`` and If the deprecated or unavailable declaration is used, the message will be incorporated into the appropriate diagnostic: -.. code-block:: c++ +.. code-block:: none harmless.c:4:3: warning: 'explode' is deprecated: extremely unsafe, use 'combust' instead!!! [-Wdeprecated-declarations] @@ -1022,6 +1022,7 @@ The following type trait primitives are supported by Clang: * ``__is_nothrow_assignable`` (MSVC 2013, clang) * ``__is_constructible`` (MSVC 2013, clang) * ``__is_nothrow_constructible`` (MSVC 2013, clang) +* ``__is_assignable`` (MSVC 2015, clang) Blocks ====== @@ -1505,6 +1506,35 @@ C-style cast applied to each element of the first argument. Query for this feature with ``__has_builtin(__builtin_convertvector)``. +``__builtin_bitreverse`` +------------------------ + +* ``__builtin_bitreverse8`` +* ``__builtin_bitreverse16`` +* ``__builtin_bitreverse32`` +* ``__builtin_bitreverse64`` + +**Syntax**: + +.. code-block:: c++ + + __builtin_bitreverse32(x) + +**Examples**: + +.. code-block:: c++ + + uint8_t rev_x = __builtin_bitreverse8(x); + uint16_t rev_x = __builtin_bitreverse16(x); + uint32_t rev_y = __builtin_bitreverse32(y); + uint64_t rev_z = __builtin_bitreverse64(z); + +**Description**: + +The '``__builtin_bitreverse``' family of builtins is used to reverse +the bitpattern of an integer value; for example ``0b10110110`` becomes +``0b01101101``. + ``__builtin_unreachable`` ------------------------- @@ -1728,6 +1758,24 @@ convert their operands before performing the operation. Query for this feature with ``__has_builtin(__builtin_add_overflow)``, etc. +Floating point builtins +--------------------------------------- + +``__builtin_canonicalize`` +-------------------------- + +.. code-block:: c + + double __builtin_canonicalize(double); + float __builtin_canonicalizef(float); + long double__builtin_canonicalizel(long double); + +Returns the platform specific canonical encoding of a floating point +number. This canonicalization is useful for implementing certain +numeric primitives such as frexp. See `LLVM canonicalize intrinsic +`_ for +more information on the semantics. + .. _langext-__c11_atomic: __c11_atomic builtins @@ -1857,7 +1905,7 @@ in the `ARM C Language Extensions Release 2.0 `_. Note that these intrinsics are implemented as motion barriers that block reordering of memory accesses and side effect instructions. Other instructions -like simple arithmatic may be reordered around the intrinsic. If you expect to +like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. X86/X86-64 Language Extensions @@ -1865,12 +1913,13 @@ X86/X86-64 Language Extensions The X86 backend has these language extensions: -Memory references off the GS segment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Memory references to specified segments +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Annotating a pointer with address space #256 causes it to be code generated -relative to the X86 GS segment register, and address space #257 causes it to be -relative to the X86 FS segment. Note that this is a very very low-level +relative to the X86 GS segment register, address space #257 causes it to be +relative to the X86 FS segment, and address space #258 causes it to be +relative to the X86 SS segment. Note that this is a very very low-level feature that should only be used if you know what you're doing (for example in an OS kernel). @@ -2001,9 +2050,9 @@ Extensions for loop hint optimizations The ``#pragma clang loop`` directive is used to specify hints for optimizing the subsequent for, while, do-while, or c++11 range-based for loop. The directive -provides options for vectorization, interleaving, and unrolling. Loop hints can -be specified before any loop and will be ignored if the optimization is not safe -to apply. +provides options for vectorization, interleaving, unrolling and +distribution. Loop hints can be specified before any loop and will be ignored if +the optimization is not safe to apply. Vectorization and Interleaving ------------------------------ @@ -2098,6 +2147,38 @@ to the same code size limit as with ``unroll(enable)``. Unrolling of a loop can be prevented by specifying ``unroll(disable)``. +Loop Distribution +----------------- + +Loop Distribution allows splitting a loop into multiple loops. This is +beneficial for example when the entire loop cannot be vectorized but some of the +resulting loops can. + +If ``distribute(enable))`` is specified and the loop has memory dependencies +that inhibit vectorization, the compiler will attempt to isolate the offending +operations into a new loop. This optimization is not enabled by default, only +loops marked with the pragma are considered. + +.. code-block:: c++ + + #pragma clang loop distribute(enable) + for (i = 0; i < N; ++i) { + S1: A[i + 1] = A[i] + B[i]; + S2: C[i] = D[i] * E[i]; + } + +This loop will be split into two loops between statements S1 and S2. The +second loop containing S2 will be vectorized. + +Loop Distribution is currently not enabled by default in the optimizer because +it can hurt performance in some cases. For example, instruction-level +parallelism could be reduced by sequentializing the execution of the +statements S1 and S2 above. + +If Loop Distribution is turned on globally with +``-mllvm -enable-loop-distribution``, specifying ``distribute(disable)`` can +be used the disable it on a per-loop basis. + Additional Information ---------------------- diff --git a/docs/LeakSanitizer.rst b/docs/LeakSanitizer.rst index 85918088ccd..c3cceccd287 100644 --- a/docs/LeakSanitizer.rst +++ b/docs/LeakSanitizer.rst @@ -9,21 +9,39 @@ Introduction ============ LeakSanitizer is a run-time memory leak detector. It can be combined with -:doc:`AddressSanitizer` to get both memory error and leak detection. -LeakSanitizer does not introduce any additional slowdown when used in this mode. -The LeakSanitizer runtime can also be linked in separately to get leak detection -only, at a minimal performance cost. - -Current status -============== - -LeakSanitizer is turned on by default, but it is only supported on x86\_64 -Linux. - -The combined mode has been tested on fairly large software projects. The -stand-alone mode has received much less testing. - -There are plans to support LeakSanitizer in :doc:`MemorySanitizer` builds. +:doc:`AddressSanitizer` to get both memory error and leak detection, or +used in a stand-alone mode. LSan adds almost no performance overhead +until the very end of the process, at which point there is an extra leak +detection phase. + +Usage +===== + +LeakSanitizer is only supported on x86\_64 Linux. In order to use it, +simply build your program with :doc:`AddressSanitizer`: + +.. code-block:: console + + $ cat memory-leak.c + #include + void *p; + int main() { + p = malloc(7); + p = 0; // The memory is leaked here. + return 0; + } + % clang -fsanitize=address -g memory-leak.c ; ./a.out + ==23646==ERROR: LeakSanitizer: detected memory leaks + Direct leak of 7 byte(s) in 1 object(s) allocated from: + #0 0x4af01b in __interceptor_malloc /projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3 + #1 0x4da26a in main memory-leak.c:4:7 + #2 0x7f076fd9cec4 in __libc_start_main libc-start.c:287 + SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s). + +To use LeakSanitizer in stand-alone mode, link your program with +``-fsanitize=leak`` flag. Make sure to use ``clang`` (not ``ld``) for the +link step, so that it would link in proper LeakSanitizer run-time library +into the final executable. More Information ================ diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 48f061c60c7..70c83ea5cca 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -100,7 +100,7 @@

Node Matchers

Return typeNameParameters -Matcher<CXXCtorInitializer>cxxCtorInitializerMatcher<CXXCtorInitializer>... +Matcher<CXXCtorInitializer>cxxCtorInitializerMatcher<CXXCtorInitializer>...
Matches constructor initializers.
 
 Examples matches i(42).
@@ -111,7 +111,7 @@ 

Node Matchers

-Matcher<Decl>accessSpecDeclMatcher<AccessSpecDecl>... +Matcher<Decl>accessSpecDeclMatcher<AccessSpecDecl>...
Matches C++ access specifier declarations.
 
 Given
@@ -124,7 +124,7 @@ 

Node Matchers

-Matcher<Decl>classTemplateDeclMatcher<ClassTemplateDecl>... +Matcher<Decl>classTemplateDeclMatcher<ClassTemplateDecl>...
Matches C++ class template declarations.
 
 Example matches Z
@@ -132,7 +132,7 @@ 

Node Matchers

-Matcher<Decl>classTemplateSpecializationDeclMatcher<ClassTemplateSpecializationDecl>... +Matcher<Decl>classTemplateSpecializationDeclMatcher<ClassTemplateSpecializationDecl>...
Matches C++ class template specializations.
 
 Given
@@ -144,7 +144,7 @@ 

Node Matchers

-Matcher<Decl>cxxConstructorDeclMatcher<CXXConstructorDecl>... +Matcher<Decl>cxxConstructorDeclMatcher<CXXConstructorDecl>...
Matches C++ constructor declarations.
 
 Example matches Foo::Foo() and Foo::Foo(int)
@@ -157,7 +157,7 @@ 

Node Matchers

-Matcher<Decl>cxxConversionDeclMatcher<CXXConversionDecl>... +Matcher<Decl>cxxConversionDeclMatcher<CXXConversionDecl>...
Matches conversion operator declarations.
 
 Example matches the operator.
@@ -165,7 +165,7 @@ 

Node Matchers

-Matcher<Decl>cxxDestructorDeclMatcher<CXXDestructorDecl>... +Matcher<Decl>cxxDestructorDeclMatcher<CXXDestructorDecl>...
Matches explicit C++ destructor declarations.
 
 Example matches Foo::~Foo()
@@ -176,7 +176,7 @@ 

Node Matchers

-Matcher<Decl>cxxMethodDeclMatcher<CXXMethodDecl>... +Matcher<Decl>cxxMethodDeclMatcher<CXXMethodDecl>...
Matches method declarations.
 
 Example matches y
@@ -184,7 +184,7 @@ 

Node Matchers

-Matcher<Decl>cxxRecordDeclMatcher<CXXRecordDecl>... +Matcher<Decl>cxxRecordDeclMatcher<CXXRecordDecl>...
Matches C++ class declarations.
 
 Example matches X, Z
@@ -193,7 +193,7 @@ 

Node Matchers

-Matcher<Decl>declMatcher<Decl>... +Matcher<Decl>declMatcher<Decl>...
Matches declarations.
 
 Examples matches X, C, and the friend declaration inside C;
@@ -204,7 +204,7 @@ 

Node Matchers

-Matcher<Decl>declaratorDeclMatcher<DeclaratorDecl>... +Matcher<Decl>declaratorDeclMatcher<DeclaratorDecl>...
Matches declarator declarations (field, variable, function
 and non-type template parameter declarations).
 
@@ -215,7 +215,7 @@ 

Node Matchers

-Matcher<Decl>enumConstantDeclMatcher<EnumConstantDecl>... +Matcher<Decl>enumConstantDeclMatcher<EnumConstantDecl>...
Matches enum constants.
 
 Example matches A, B, C
@@ -225,7 +225,7 @@ 

Node Matchers

-Matcher<Decl>enumDeclMatcher<EnumDecl>... +Matcher<Decl>enumDeclMatcher<EnumDecl>...
Matches enum declarations.
 
 Example matches X
@@ -235,7 +235,7 @@ 

Node Matchers

-Matcher<Decl>fieldDeclMatcher<FieldDecl>... +Matcher<Decl>fieldDeclMatcher<FieldDecl>...
Matches field declarations.
 
 Given
@@ -245,7 +245,7 @@ 

Node Matchers

-Matcher<Decl>friendDeclMatcher<FriendDecl>... +Matcher<Decl>friendDeclMatcher<FriendDecl>...
Matches friend declarations.
 
 Given
@@ -255,7 +255,7 @@ 

Node Matchers

-Matcher<Decl>functionDeclMatcher<FunctionDecl>... +Matcher<Decl>functionDeclMatcher<FunctionDecl>...
Matches function declarations.
 
 Example matches f
@@ -263,7 +263,7 @@ 

Node Matchers

-Matcher<Decl>functionTemplateDeclMatcher<FunctionTemplateDecl>... +Matcher<Decl>functionTemplateDeclMatcher<FunctionTemplateDecl>...
Matches C++ function template declarations.
 
 Example matches f
@@ -271,7 +271,18 @@ 

Node Matchers

-Matcher<Decl>linkageSpecDeclMatcher<LinkageSpecDecl>... +Matcher<Decl>labelDeclMatcher<LabelDecl>... +
Matches a declaration of label.
+
+Given
+  goto FOO;
+  FOO: bar();
+labelDecl()
+  matches 'FOO:'
+
+ + +Matcher<Decl>linkageSpecDeclMatcher<LinkageSpecDecl>...
Matches a declaration of a linkage specification.
 
 Given
@@ -281,7 +292,7 @@ 

Node Matchers

-Matcher<Decl>namedDeclMatcher<NamedDecl>... +Matcher<Decl>namedDeclMatcher<NamedDecl>...
Matches a declaration of anything that could have a name.
 
 Example matches X, S, the anonymous union type, i, and U;
@@ -294,7 +305,7 @@ 

Node Matchers

-Matcher<Decl>namespaceAliasDeclMatcher<NamespaceAliasDecl>... +Matcher<Decl>namespaceAliasDeclMatcher<NamespaceAliasDecl>...
Matches a declaration of a namespace alias.
 
 Given
@@ -305,7 +316,7 @@ 

Node Matchers

-Matcher<Decl>namespaceDeclMatcher<NamespaceDecl>... +Matcher<Decl>namespaceDeclMatcher<NamespaceDecl>...
Matches a declaration of a namespace.
 
 Given
@@ -316,7 +327,7 @@ 

Node Matchers

-Matcher<Decl>nonTypeTemplateParmDeclMatcher<NonTypeTemplateParmDecl>... +Matcher<Decl>nonTypeTemplateParmDeclMatcher<NonTypeTemplateParmDecl>...
Matches non-type template parameter declarations.
 
 Given
@@ -326,7 +337,7 @@ 

Node Matchers

-Matcher<Decl>objcInterfaceDeclMatcher<ObjCInterfaceDecl>... +Matcher<Decl>objcInterfaceDeclMatcher<ObjCInterfaceDecl>...
Matches Objective-C interface declarations.
 
 Example matches Foo
@@ -335,7 +346,7 @@ 

Node Matchers

-Matcher<Decl>parmVarDeclMatcher<ParmVarDecl>... +Matcher<Decl>parmVarDeclMatcher<ParmVarDecl>...
Matches parameter variable declarations.
 
 Given
@@ -345,7 +356,7 @@ 

Node Matchers

-Matcher<Decl>recordDeclMatcher<RecordDecl>... +Matcher<Decl>recordDeclMatcher<RecordDecl>...
Matches class, struct, and union declarations.
 
 Example matches X, Z, U, and S
@@ -356,7 +367,7 @@ 

Node Matchers

-Matcher<Decl>staticAssertDeclMatcher<StaticAssertDecl>... +Matcher<Decl>staticAssertDeclMatcher<StaticAssertDecl>...
Matches a C++ static_assert declaration.
 
 Example:
@@ -371,7 +382,7 @@ 

Node Matchers

-Matcher<Decl>templateTypeParmDeclMatcher<TemplateTypeParmDecl>... +Matcher<Decl>templateTypeParmDeclMatcher<TemplateTypeParmDecl>...
Matches template type parameter declarations.
 
 Given
@@ -381,7 +392,7 @@ 

Node Matchers

-Matcher<Decl>translationUnitDeclMatcher<TranslationUnitDecl>... +Matcher<Decl>translationUnitDeclMatcher<TranslationUnitDecl>...
Matches the top declaration context.
 
 Given
@@ -394,17 +405,40 @@ 

Node Matchers

-Matcher<Decl>typedefDeclMatcher<TypedefDecl>... +Matcher<Decl>typeAliasDeclMatcher<TypeAliasDecl>... +
Matches type alias declarations.
+
+Given
+  typedef int X;
+  using Y = int;
+typeAliasDecl()
+  matches "using Y = int", but not "typedef int X"
+
+ + +Matcher<Decl>typedefDeclMatcher<TypedefDecl>...
Matches typedef declarations.
 
 Given
   typedef int X;
+  using Y = int;
 typedefDecl()
-  matches "typedef int X"
+  matches "typedef int X", but not "using Y = int"
+
+ + +Matcher<Decl>typedefNameDeclMatcher<TypedefNameDecl>... +
Matches typedef name declarations.
+
+Given
+  typedef int X;
+  using Y = int;
+typedefNameDecl()
+  matches "typedef int X" and "using Y = int"
 
-Matcher<Decl>unresolvedUsingTypenameDeclMatcher<UnresolvedUsingTypenameDecl>... +Matcher<Decl>unresolvedUsingTypenameDeclMatcher<UnresolvedUsingTypenameDecl>...
Matches unresolved using value declarations that involve the
 typename.
 
@@ -420,7 +454,7 @@ 

Node Matchers

matches using Base<T>::Foo
-Matcher<Decl>unresolvedUsingValueDeclMatcher<UnresolvedUsingValueDecl>... +Matcher<Decl>unresolvedUsingValueDeclMatcher<UnresolvedUsingValueDecl>...
Matches unresolved using value declarations.
 
 Given
@@ -432,7 +466,7 @@ 

Node Matchers

matches using X::x
-Matcher<Decl>usingDeclMatcher<UsingDecl>... +Matcher<Decl>usingDeclMatcher<UsingDecl>...
Matches using declarations.
 
 Given
@@ -442,7 +476,7 @@ 

Node Matchers

matches using X::x
-Matcher<Decl>usingDirectiveDeclMatcher<UsingDirectiveDecl>... +Matcher<Decl>usingDirectiveDeclMatcher<UsingDirectiveDecl>...
Matches using namespace declarations.
 
 Given
@@ -452,7 +486,7 @@ 

Node Matchers

matches using namespace X
-Matcher<Decl>valueDeclMatcher<ValueDecl>... +Matcher<Decl>valueDeclMatcher<ValueDecl>...
Matches any value declaration.
 
 Example matches A, B, C and F
@@ -461,7 +495,7 @@ 

Node Matchers

-Matcher<Decl>varDeclMatcher<VarDecl>... +Matcher<Decl>varDeclMatcher<VarDecl>...
Matches variable declarations.
 
 Note: this does not match declarations of member variables, which are
@@ -472,12 +506,12 @@ 

Node Matchers

-Matcher<NestedNameSpecifierLoc>nestedNameSpecifierLocMatcher<NestedNameSpecifierLoc>... +Matcher<NestedNameSpecifierLoc>nestedNameSpecifierLocMatcher<NestedNameSpecifierLoc>...
Same as nestedNameSpecifier but matches NestedNameSpecifierLoc.
 
-Matcher<NestedNameSpecifier>nestedNameSpecifierMatcher<NestedNameSpecifier>... +Matcher<NestedNameSpecifier>nestedNameSpecifierMatcher<NestedNameSpecifier>...
Matches nested name specifiers.
 
 Given
@@ -492,12 +526,24 @@ 

Node Matchers

-Matcher<QualType>qualTypeMatcher<QualType>... +Matcher<QualType>qualTypeMatcher<QualType>...
Matches QualTypes in the clang AST.
 
-Matcher<Stmt>arraySubscriptExprMatcher<ArraySubscriptExpr>... +Matcher<Stmt>addrLabelExprMatcher<AddrLabelExpr>... +
Matches address of label statements (GNU extension).
+
+Given
+  FOO: bar();
+  void *ptr = &&FOO;
+  goto *bar;
+addrLabelExpr()
+  matches '&&FOO'
+
+ + +Matcher<Stmt>arraySubscriptExprMatcher<ArraySubscriptExpr>...
Matches array subscript expressions.
 
 Given
@@ -507,7 +553,7 @@ 

Node Matchers

-Matcher<Stmt>asmStmtMatcher<AsmStmt>... +Matcher<Stmt>asmStmtMatcher<AsmStmt>...
Matches asm statements.
 
  int i = 100;
@@ -517,7 +563,22 @@ 

Node Matchers

-Matcher<Stmt>binaryOperatorMatcher<BinaryOperator>... +Matcher<Stmt>atomicExprMatcher<AtomicExpr>... +
Matches atomic builtins.
+Example matches __atomic_load_n(ptr, 1)
+  void foo() { int *ptr; __atomic_load_n(ptr, 1); }
+
+ + +Matcher<Stmt>binaryConditionalOperatorMatcher<BinaryConditionalOperator>... +
Matches binary conditional operator expressions (GNU extension).
+
+Example matches a ?: b
+  (a ?: b) + 42;
+
+ + +Matcher<Stmt>binaryOperatorMatcher<BinaryOperator>...
Matches binary operator expressions.
 
 Example matches a || b
@@ -525,7 +586,7 @@ 

Node Matchers

-Matcher<Stmt>breakStmtMatcher<BreakStmt>... +Matcher<Stmt>breakStmtMatcher<BreakStmt>...
Matches break statements.
 
 Given
@@ -535,7 +596,7 @@ 

Node Matchers

-Matcher<Stmt>cStyleCastExprMatcher<CStyleCastExpr>... +Matcher<Stmt>cStyleCastExprMatcher<CStyleCastExpr>...
Matches a C-style cast expression.
 
 Example: Matches (int*) 2.2f in
@@ -543,7 +604,7 @@ 

Node Matchers

-Matcher<Stmt>callExprMatcher<CallExpr>... +Matcher<Stmt>callExprMatcher<CallExpr>...
Matches call expressions.
 
 Example matches x.y() and y()
@@ -553,7 +614,7 @@ 

Node Matchers

-Matcher<Stmt>caseStmtMatcher<CaseStmt>... +Matcher<Stmt>caseStmtMatcher<CaseStmt>...
Matches case statements inside switch statements.
 
 Given
@@ -563,7 +624,7 @@ 

Node Matchers

-Matcher<Stmt>castExprMatcher<CastExpr>... +Matcher<Stmt>castExprMatcher<CastExpr>...
Matches any cast nodes of Clang's AST.
 
 Example: castExpr() matches each of the following:
@@ -576,26 +637,28 @@ 

Node Matchers

-Matcher<Stmt>characterLiteralMatcher<CharacterLiteral>... +Matcher<Stmt>characterLiteralMatcher<CharacterLiteral>...
Matches character literals (also matches wchar_t).
 
 Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
 though.
 
 Example matches 'a', L'a'
-  char ch = 'a'; wchar_t chw = L'a';
+  char ch = 'a';
+  wchar_t chw = L'a';
 
-Matcher<Stmt>compoundLiteralExprMatcher<CompoundLiteralExpr>... +Matcher<Stmt>compoundLiteralExprMatcher<CompoundLiteralExpr>...
Matches compound (i.e. non-scalar) literals
 
 Example match: {1}, (1, 2)
-  int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+  int array[4] = {1};
+  vector int myvec = (vector int)(1, 2);
 
-Matcher<Stmt>compoundStmtMatcher<CompoundStmt>... +Matcher<Stmt>compoundStmtMatcher<CompoundStmt>...
Matches compound statements.
 
 Example matches '{}' and '{{}}'in 'for (;;) {{}}'
@@ -603,7 +666,7 @@ 

Node Matchers

-Matcher<Stmt>conditionalOperatorMatcher<ConditionalOperator>... +Matcher<Stmt>conditionalOperatorMatcher<ConditionalOperator>...
Matches conditional operator expressions.
 
 Example matches a ? b : c
@@ -611,7 +674,7 @@ 

Node Matchers

-Matcher<Stmt>continueStmtMatcher<ContinueStmt>... +Matcher<Stmt>continueStmtMatcher<ContinueStmt>...
Matches continue statements.
 
 Given
@@ -621,7 +684,7 @@ 

Node Matchers

-Matcher<Stmt>cudaKernelCallExprMatcher<CUDAKernelCallExpr>... +Matcher<Stmt>cudaKernelCallExprMatcher<CUDAKernelCallExpr>...
Matches CUDA kernel call expression.
 
 Example matches,
@@ -629,7 +692,7 @@ 

Node Matchers

-Matcher<Stmt>cxxBindTemporaryExprMatcher<CXXBindTemporaryExpr>... +Matcher<Stmt>cxxBindTemporaryExprMatcher<CXXBindTemporaryExpr>...
Matches nodes where temporaries are created.
 
 Example matches FunctionTakesString(GetStringByValue())
@@ -639,7 +702,7 @@ 

Node Matchers

-Matcher<Stmt>cxxBoolLiteralMatcher<CXXBoolLiteralExpr>... +Matcher<Stmt>cxxBoolLiteralMatcher<CXXBoolLiteralExpr>...
Matches bool literals.
 
 Example matches true
@@ -647,7 +710,7 @@ 

Node Matchers

-Matcher<Stmt>cxxCatchStmtMatcher<CXXCatchStmt>... +Matcher<Stmt>cxxCatchStmtMatcher<CXXCatchStmt>...
Matches catch statements.
 
   try {} catch(int i) {}
@@ -656,7 +719,7 @@ 

Node Matchers

-Matcher<Stmt>cxxConstCastExprMatcher<CXXConstCastExpr>... +Matcher<Stmt>cxxConstCastExprMatcher<CXXConstCastExpr>...
Matches a const_cast expression.
 
 Example: Matches const_cast<int*>(&r) in
@@ -666,7 +729,7 @@ 

Node Matchers

-Matcher<Stmt>cxxConstructExprMatcher<CXXConstructExpr>... +Matcher<Stmt>cxxConstructExprMatcher<CXXConstructExpr>...
Matches constructor call expressions (including implicit ones).
 
 Example matches string(ptr, n) and ptr within arguments of f
@@ -678,7 +741,7 @@ 

Node Matchers

-Matcher<Stmt>cxxDefaultArgExprMatcher<CXXDefaultArgExpr>... +Matcher<Stmt>cxxDefaultArgExprMatcher<CXXDefaultArgExpr>...
Matches the value of a default argument at the call site.
 
 Example matches the CXXDefaultArgExpr placeholder inserted for the
@@ -689,7 +752,7 @@ 

Node Matchers

-Matcher<Stmt>cxxDeleteExprMatcher<CXXDeleteExpr>... +Matcher<Stmt>cxxDeleteExprMatcher<CXXDeleteExpr>...
Matches delete expressions.
 
 Given
@@ -699,7 +762,7 @@ 

Node Matchers

-Matcher<Stmt>cxxDynamicCastExprMatcher<CXXDynamicCastExpr>... +Matcher<Stmt>cxxDynamicCastExprMatcher<CXXDynamicCastExpr>...
Matches a dynamic_cast expression.
 
 Example:
@@ -713,7 +776,7 @@ 

Node Matchers

-Matcher<Stmt>cxxForRangeStmtMatcher<CXXForRangeStmt>... +Matcher<Stmt>cxxForRangeStmtMatcher<CXXForRangeStmt>...
Matches range-based for statements.
 
 cxxForRangeStmt() matches 'for (auto a : i)'
@@ -722,7 +785,7 @@ 

Node Matchers

-Matcher<Stmt>cxxFunctionalCastExprMatcher<CXXFunctionalCastExpr>... +Matcher<Stmt>cxxFunctionalCastExprMatcher<CXXFunctionalCastExpr>...
Matches functional cast expressions
 
 Example: Matches Foo(bar);
@@ -732,7 +795,7 @@ 

Node Matchers

-Matcher<Stmt>cxxMemberCallExprMatcher<CXXMemberCallExpr>... +Matcher<Stmt>cxxMemberCallExprMatcher<CXXMemberCallExpr>...
Matches member call expressions.
 
 Example matches x.y()
@@ -741,7 +804,7 @@ 

Node Matchers

-Matcher<Stmt>cxxNewExprMatcher<CXXNewExpr>... +Matcher<Stmt>cxxNewExprMatcher<CXXNewExpr>...
Matches new expressions.
 
 Given
@@ -751,12 +814,12 @@ 

Node Matchers

-Matcher<Stmt>cxxNullPtrLiteralExprMatcher<CXXNullPtrLiteralExpr>... +Matcher<Stmt>cxxNullPtrLiteralExprMatcher<CXXNullPtrLiteralExpr>...
Matches nullptr literal.
 
-Matcher<Stmt>cxxOperatorCallExprMatcher<CXXOperatorCallExpr>... +Matcher<Stmt>cxxOperatorCallExprMatcher<CXXOperatorCallExpr>...
Matches overloaded operator calls.
 
 Note that if an operator isn't overloaded, it won't match. Instead, use
@@ -772,7 +835,7 @@ 

Node Matchers

-Matcher<Stmt>cxxReinterpretCastExprMatcher<CXXReinterpretCastExpr>... +Matcher<Stmt>cxxReinterpretCastExprMatcher<CXXReinterpretCastExpr>...
Matches a reinterpret_cast expression.
 
 Either the source expression or the destination type can be matched
@@ -784,11 +847,11 @@ 

Node Matchers

-Matcher<Stmt>cxxStaticCastExprMatcher<CXXStaticCastExpr>... +Matcher<Stmt>cxxStaticCastExprMatcher<CXXStaticCastExpr>...
Matches a C++ static_cast expression.
 
-hasDestinationType
-reinterpretCast
+See also: hasDestinationType
+See also: reinterpretCast
 
 Example:
   cxxStaticCastExpr()
@@ -799,7 +862,7 @@ 

Node Matchers

-Matcher<Stmt>cxxTemporaryObjectExprMatcher<CXXTemporaryObjectExpr>... +Matcher<Stmt>cxxTemporaryObjectExprMatcher<CXXTemporaryObjectExpr>...
Matches functional cast expressions having N != 1 arguments
 
 Example: Matches Foo(bar, bar)
@@ -807,7 +870,7 @@ 

Node Matchers

-Matcher<Stmt>cxxThisExprMatcher<CXXThisExpr>... +Matcher<Stmt>cxxThisExprMatcher<CXXThisExpr>...
Matches implicit and explicit this expressions.
 
 Example matches the implicit this expression in "return i".
@@ -819,7 +882,7 @@ 

Node Matchers

-Matcher<Stmt>cxxThrowExprMatcher<CXXThrowExpr>... +Matcher<Stmt>cxxThrowExprMatcher<CXXThrowExpr>...
Matches throw expressions.
 
   try { throw 5; } catch(int i) {}
@@ -828,7 +891,7 @@ 

Node Matchers

-Matcher<Stmt>cxxTryStmtMatcher<CXXTryStmt>... +Matcher<Stmt>cxxTryStmtMatcher<CXXTryStmt>...
Matches try statements.
 
   try {} catch(int i) {}
@@ -837,7 +900,7 @@ 

Node Matchers

-Matcher<Stmt>cxxUnresolvedConstructExprMatcher<CXXUnresolvedConstructExpr>... +Matcher<Stmt>cxxUnresolvedConstructExprMatcher<CXXUnresolvedConstructExpr>...
Matches unresolved constructor call expressions.
 
 Example matches T(t) in return statement of f
@@ -847,7 +910,7 @@ 

Node Matchers

-Matcher<Stmt>declRefExprMatcher<DeclRefExpr>... +Matcher<Stmt>declRefExprMatcher<DeclRefExpr>...
Matches expressions that refer to declarations.
 
 Example matches x in if (x)
@@ -856,7 +919,7 @@ 

Node Matchers

-Matcher<Stmt>declStmtMatcher<DeclStmt>... +Matcher<Stmt>declStmtMatcher<DeclStmt>...
Matches declaration statements.
 
 Given
@@ -866,7 +929,7 @@ 

Node Matchers

-Matcher<Stmt>defaultStmtMatcher<DefaultStmt>... +Matcher<Stmt>defaultStmtMatcher<DefaultStmt>...
Matches default statements inside switch statements.
 
 Given
@@ -876,7 +939,15 @@ 

Node Matchers

-Matcher<Stmt>doStmtMatcher<DoStmt>... +Matcher<Stmt>designatedInitExprMatcher<DesignatedInitExpr>... +
Matches C99 designated initializer expressions [C99 6.7.8].
+
+Example: Matches { [2].y = 1.0, [0].x = 1.0 }
+  point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
+
+ + +Matcher<Stmt>doStmtMatcher<DoStmt>...
Matches do statements.
 
 Given
@@ -886,7 +957,7 @@ 

Node Matchers

-Matcher<Stmt>explicitCastExprMatcher<ExplicitCastExpr>... +Matcher<Stmt>explicitCastExprMatcher<ExplicitCastExpr>...
Matches explicit cast expressions.
 
 Matches any cast expression written in user code, whether it be a
@@ -898,7 +969,7 @@ 

Node Matchers

Clang uses the term "cast" to apply to implicit conversions as well as to actual cast expressions. -hasDestinationType. +See also: hasDestinationType. Example: matches all five of the casts in int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42))))) @@ -907,7 +978,7 @@

Node Matchers

-Matcher<Stmt>exprMatcher<Expr>... +Matcher<Stmt>exprMatcher<Expr>...
Matches expressions.
 
 Example matches x()
@@ -915,7 +986,7 @@ 

Node Matchers

-Matcher<Stmt>exprWithCleanupsMatcher<ExprWithCleanups>... +Matcher<Stmt>exprWithCleanupsMatcher<ExprWithCleanups>...
Matches expressions that introduce cleanups to be run at the end
 of the sub-expression's evaluation.
 
@@ -924,7 +995,7 @@ 

Node Matchers

-Matcher<Stmt>floatLiteralMatcher<FloatingLiteral>... +Matcher<Stmt>floatLiteralMatcher<FloatingLiteral>...
Matches float literals of all sizes encodings, e.g.
 1.0, 1.0f, 1.0L and 1e10.
 
@@ -933,7 +1004,7 @@ 

Node Matchers

-Matcher<Stmt>forStmtMatcher<ForStmt>... +Matcher<Stmt>forStmtMatcher<ForStmt>...
Matches for statements.
 
 Example matches 'for (;;) {}'
@@ -942,12 +1013,12 @@ 

Node Matchers

-Matcher<Stmt>gnuNullExprMatcher<GNUNullExpr>... +Matcher<Stmt>gnuNullExprMatcher<GNUNullExpr>...
Matches GNU __null expression.
 
-Matcher<Stmt>gotoStmtMatcher<GotoStmt>... +Matcher<Stmt>gotoStmtMatcher<GotoStmt>...
Matches goto statements.
 
 Given
@@ -958,7 +1029,7 @@ 

Node Matchers

-Matcher<Stmt>ifStmtMatcher<IfStmt>... +Matcher<Stmt>ifStmtMatcher<IfStmt>...
Matches if statements.
 
 Example matches 'if (x) {}'
@@ -966,7 +1037,7 @@ 

Node Matchers

-Matcher<Stmt>implicitCastExprMatcher<ImplicitCastExpr>... +Matcher<Stmt>implicitCastExprMatcher<ImplicitCastExpr>...
Matches the implicit cast nodes of Clang's AST.
 
 This matches many different places, including function call return value
@@ -974,7 +1045,17 @@ 

Node Matchers

-Matcher<Stmt>initListExprMatcher<InitListExpr>... +Matcher<Stmt>implicitValueInitExprMatcher<ImplicitValueInitExpr>... +
Matches implicit initializers of init list expressions.
+
+Given
+  point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
+implicitValueInitExpr()
+  matches "[0].y" (implicitly)
+
+ + +Matcher<Stmt>initListExprMatcher<InitListExpr>...
Matches init list expressions.
 
 Given
@@ -986,7 +1067,7 @@ 

Node Matchers

-Matcher<Stmt>integerLiteralMatcher<IntegerLiteral>... +Matcher<Stmt>integerLiteralMatcher<IntegerLiteral>...
Matches integer literals of all sizes encodings, e.g.
 1, 1L, 0x1 and 1U.
 
@@ -994,7 +1075,7 @@ 

Node Matchers

-Matcher<Stmt>labelStmtMatcher<LabelStmt>... +Matcher<Stmt>labelStmtMatcher<LabelStmt>...
Matches label statements.
 
 Given
@@ -1005,7 +1086,7 @@ 

Node Matchers

-Matcher<Stmt>lambdaExprMatcher<LambdaExpr>... +Matcher<Stmt>lambdaExprMatcher<LambdaExpr>...
Matches lambda expressions.
 
 Example matches [&](){return 5;}
@@ -1013,7 +1094,7 @@ 

Node Matchers

-Matcher<Stmt>materializeTemporaryExprMatcher<MaterializeTemporaryExpr>... +Matcher<Stmt>materializeTemporaryExprMatcher<MaterializeTemporaryExpr>...
Matches nodes where temporaries are materialized.
 
 Example: Given
@@ -1029,7 +1110,7 @@ 

Node Matchers

-Matcher<Stmt>memberExprMatcher<MemberExpr>... +Matcher<Stmt>memberExprMatcher<MemberExpr>...
Matches member expressions.
 
 Given
@@ -1042,7 +1123,7 @@ 

Node Matchers

-Matcher<Stmt>nullStmtMatcher<NullStmt>... +Matcher<Stmt>nullStmtMatcher<NullStmt>...
Matches null statements.
 
   foo();;
@@ -1051,7 +1132,7 @@ 

Node Matchers

-Matcher<Stmt>objcMessageExprMatcher<ObjCMessageExpr>... +Matcher<Stmt>objcMessageExprMatcher<ObjCMessageExpr>...
Matches ObjectiveC Message invocation expressions.
 
 The innermost message send invokes the "alloc" class method on the
@@ -1062,7 +1143,51 @@ 

Node Matchers

-Matcher<Stmt>returnStmtMatcher<ReturnStmt>... +Matcher<Stmt>opaqueValueExprMatcher<OpaqueValueExpr>... +
Matches opaque value expressions. They are used as helpers
+to reference another expressions and can be met
+in BinaryConditionalOperators, for example.
+
+Example matches 'a'
+  (a ?: c) + 42;
+
+ + +Matcher<Stmt>parenExprMatcher<ParenExpr>... +
Matches parentheses used in expressions.
+
+Example matches (foo() + 1)
+  int foo() { return 1; }
+  int a = (foo() + 1);
+
+ + +Matcher<Stmt>parenListExprMatcher<ParenListExpr>... +
Matches paren list expressions.
+ParenListExprs don't have a predefined type and are used for late parsing.
+In the final AST, they can be met in template declarations.
+
+Given
+  template<typename T> class X {
+    void f() {
+      X x(*this);
+      int a = 0, b = 1; int i = (a, b);
+    }
+  };
+parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
+has a predefined type and is a ParenExpr, not a ParenListExpr.
+
+ + +Matcher<Stmt>predefinedExprMatcher<PredefinedExpr>... +
Matches predefined identifier expressions [C99 6.4.2.2].
+
+Example: Matches __func__
+  printf("%s", __func__);
+
+ + +Matcher<Stmt>returnStmtMatcher<ReturnStmt>...
Matches return statements.
 
 Given
@@ -1072,7 +1197,7 @@ 

Node Matchers

-Matcher<Stmt>stmtMatcher<Stmt>... +Matcher<Stmt>stmtMatcher<Stmt>...
Matches statements.
 
 Given
@@ -1082,15 +1207,24 @@ 

Node Matchers

-Matcher<Stmt>stringLiteralMatcher<StringLiteral>... +Matcher<Stmt>stmtExprMatcher<StmtExpr>... +
Matches statement expression (GNU extension).
+
+Example match: ({ int X = 4; X; })
+  int C = ({ int X = 4; X; });
+
+ + +Matcher<Stmt>stringLiteralMatcher<StringLiteral>...
Matches string literals (also matches wide string literals).
 
 Example matches "abcd", L"abcd"
-  char *s = "abcd"; wchar_t *ws = L"abcd"
+  char *s = "abcd";
+  wchar_t *ws = L"abcd";
 
-Matcher<Stmt>substNonTypeTemplateParmExprMatcher<SubstNonTypeTemplateParmExpr>... +Matcher<Stmt>substNonTypeTemplateParmExprMatcher<SubstNonTypeTemplateParmExpr>...
Matches substitutions of non-type template parameters.
 
 Given
@@ -1102,7 +1236,7 @@ 

Node Matchers

-Matcher<Stmt>switchCaseMatcher<SwitchCase>... +Matcher<Stmt>switchCaseMatcher<SwitchCase>...
Matches case and default statements inside switch statements.
 
 Given
@@ -1112,7 +1246,7 @@ 

Node Matchers

-Matcher<Stmt>switchStmtMatcher<SwitchStmt>... +Matcher<Stmt>switchStmtMatcher<SwitchStmt>...
Matches switch statements.
 
 Given
@@ -1122,7 +1256,7 @@ 

Node Matchers

-Matcher<Stmt>unaryExprOrTypeTraitExprMatcher<UnaryExprOrTypeTraitExpr>... +Matcher<Stmt>unaryExprOrTypeTraitExprMatcher<UnaryExprOrTypeTraitExpr>...
Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
 
 Given
@@ -1133,7 +1267,7 @@ 

Node Matchers

-Matcher<Stmt>unaryOperatorMatcher<UnaryOperator>... +Matcher<Stmt>unaryOperatorMatcher<UnaryOperator>...
Matches unary operator expressions.
 
 Example matches !a
@@ -1141,14 +1275,29 @@ 

Node Matchers

-Matcher<Stmt>userDefinedLiteralMatcher<UserDefinedLiteral>... +Matcher<Stmt>unresolvedLookupExprMatcher<UnresolvedLookupExpr>... +
Matches reference to a name that can be looked up during parsing
+but could not be resolved to a specific declaration.
+
+Given
+  template<typename T>
+  T foo() { T a; return a; }
+  template<typename T>
+  void bar() {
+    foo<T>();
+  }
+unresolvedLookupExpr()
+  matches foo<T>() 
+ + +Matcher<Stmt>userDefinedLiteralMatcher<UserDefinedLiteral>...
Matches user defined literal operator call.
 
 Example match: "foo"_suffix
 
-Matcher<Stmt>whileStmtMatcher<WhileStmt>... +Matcher<Stmt>whileStmtMatcher<WhileStmt>...
Matches while statements.
 
 Given
@@ -1158,7 +1307,7 @@ 

Node Matchers

-Matcher<TemplateArgument>templateArgumentMatcher<TemplateArgument>... +Matcher<TemplateArgument>templateArgumentMatcher<TemplateArgument>...
Matches template arguments.
 
 Given
@@ -1169,12 +1318,12 @@ 

Node Matchers

-Matcher<TypeLoc>typeLocMatcher<TypeLoc>... +Matcher<TypeLoc>typeLocMatcher<TypeLoc>...
Matches TypeLocs in the clang AST.
 
-Matcher<Type>arrayTypeMatcher<ArrayType>... +Matcher<Type>arrayTypeMatcher<ArrayType>...
Matches all kinds of arrays.
 
 Given
@@ -1186,7 +1335,7 @@ 

Node Matchers

-Matcher<Type>atomicTypeMatcher<AtomicType>... +Matcher<Type>atomicTypeMatcher<AtomicType>...
Matches atomic types.
 
 Given
@@ -1196,7 +1345,7 @@ 

Node Matchers

-Matcher<Type>autoTypeMatcher<AutoType>... +Matcher<Type>autoTypeMatcher<AutoType>...
Matches types nodes representing C++11 auto types.
 
 Given:
@@ -1208,7 +1357,7 @@ 

Node Matchers

-Matcher<Type>blockPointerTypeMatcher<BlockPointerType>... +Matcher<Type>blockPointerTypeMatcher<BlockPointerType>...
Matches block pointer types, i.e. types syntactically represented as
 "void (^)(int)".
 
@@ -1216,7 +1365,7 @@ 

Node Matchers

-Matcher<Type>builtinTypeMatcher<BuiltinType>... +Matcher<Type>builtinTypeMatcher<BuiltinType>...
Matches builtin Types.
 
 Given
@@ -1230,7 +1379,7 @@ 

Node Matchers

-Matcher<Type>complexTypeMatcher<ComplexType>... +Matcher<Type>complexTypeMatcher<ComplexType>...
Matches C99 complex types.
 
 Given
@@ -1240,7 +1389,7 @@ 

Node Matchers

-Matcher<Type>constantArrayTypeMatcher<ConstantArrayType>... +Matcher<Type>constantArrayTypeMatcher<ConstantArrayType>...
Matches C arrays with a specified constant size.
 
 Given
@@ -1254,7 +1403,7 @@ 

Node Matchers

-Matcher<Type>decayedTypeMatcher<DecayedType>... +Matcher<Type>decayedTypeMatcher<DecayedType>...
Matches decayed type
 Example matches i[] in declaration of f.
     (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
@@ -1266,7 +1415,7 @@ 

Node Matchers

-Matcher<Type>dependentSizedArrayTypeMatcher<DependentSizedArrayType>... +Matcher<Type>dependentSizedArrayTypeMatcher<DependentSizedArrayType>...
Matches C++ arrays whose size is a value-dependent expression.
 
 Given
@@ -1279,7 +1428,7 @@ 

Node Matchers

-Matcher<Type>elaboratedTypeMatcher<ElaboratedType>... +Matcher<Type>elaboratedTypeMatcher<ElaboratedType>...
Matches types specified with an elaborated type keyword or with a
 qualified name.
 
@@ -1299,7 +1448,34 @@ 

Node Matchers

-Matcher<Type>functionTypeMatcher<FunctionType>... +Matcher<Type>enumTypeMatcher<EnumType>... +
Matches enum types.
+
+Given
+  enum C { Green };
+  enum class S { Red };
+
+  C c;
+  S s;
+
+enumType() matches the type of the variable declarations of both c and
+s.
+
+ + +Matcher<Type>functionProtoTypeMatcher<FunctionProtoType>... +
Matches FunctionProtoType nodes.
+
+Given
+  int (*f)(int);
+  void g();
+functionProtoType()
+  matches "int (*f)(int)" and the type of "g" in C++ mode.
+  In C mode, "g" is not matched because it does not contain a prototype.
+
+ + +Matcher<Type>functionTypeMatcher<FunctionType>...
Matches FunctionType nodes.
 
 Given
@@ -1310,7 +1486,7 @@ 

Node Matchers

-Matcher<Type>incompleteArrayTypeMatcher<IncompleteArrayType>... +Matcher<Type>incompleteArrayTypeMatcher<IncompleteArrayType>...
Matches C arrays with unspecified size.
 
 Given
@@ -1322,7 +1498,7 @@ 

Node Matchers

-Matcher<Type>injectedClassNameTypeMatcher<InjectedClassNameType>... +Matcher<Type>injectedClassNameTypeMatcher<InjectedClassNameType>...
Matches injected class name types.
 
 Example matches S s, but not S<T> s.
@@ -1334,7 +1510,7 @@ 

Node Matchers

-Matcher<Type>lValueReferenceTypeMatcher<LValueReferenceType>... +Matcher<Type>lValueReferenceTypeMatcher<LValueReferenceType>...
Matches lvalue reference types.
 
 Given:
@@ -1351,7 +1527,7 @@ 

Node Matchers

-Matcher<Type>memberPointerTypeMatcher<MemberPointerType>... +Matcher<Type>memberPointerTypeMatcher<MemberPointerType>...
Matches member pointer types.
 Given
   struct A { int i; }
@@ -1361,7 +1537,7 @@ 

Node Matchers

-Matcher<Type>objcObjectPointerTypeMatcher<ObjCObjectPointerType>... +Matcher<Type>objcObjectPointerTypeMatcher<ObjCObjectPointerType>...
Matches an Objective-C object pointer type, which is different from
 a pointer type, despite being syntactically similar.
 
@@ -1376,7 +1552,7 @@ 

Node Matchers

-Matcher<Type>parenTypeMatcher<ParenType>... +Matcher<Type>parenTypeMatcher<ParenType>...
Matches ParenType nodes.
 
 Given
@@ -1388,7 +1564,7 @@ 

Node Matchers

-Matcher<Type>pointerTypeMatcher<PointerType>... +Matcher<Type>pointerTypeMatcher<PointerType>...
Matches pointer types, but does not match Objective-C object pointer
 types.
 
@@ -1405,7 +1581,7 @@ 

Node Matchers

-Matcher<Type>rValueReferenceTypeMatcher<RValueReferenceType>... +Matcher<Type>rValueReferenceTypeMatcher<RValueReferenceType>...
Matches rvalue reference types.
 
 Given:
@@ -1422,7 +1598,7 @@ 

Node Matchers

-Matcher<Type>recordTypeMatcher<RecordType>... +Matcher<Type>recordTypeMatcher<RecordType>...
Matches record types (e.g. structs, classes).
 
 Given
@@ -1437,7 +1613,7 @@ 

Node Matchers

-Matcher<Type>referenceTypeMatcher<ReferenceType>... +Matcher<Type>referenceTypeMatcher<ReferenceType>...
Matches both lvalue and rvalue reference types.
 
 Given
@@ -1453,7 +1629,7 @@ 

Node Matchers

-Matcher<Type>substTemplateTypeParmTypeMatcher<SubstTemplateTypeParmType>... +Matcher<Type>substTemplateTypeParmTypeMatcher<SubstTemplateTypeParmType>...
Matches types that represent the result of substituting a type for a
 template type parameter.
 
@@ -1467,7 +1643,7 @@ 

Node Matchers

-Matcher<Type>templateSpecializationTypeMatcher<TemplateSpecializationType>... +Matcher<Type>templateSpecializationTypeMatcher<TemplateSpecializationType>...
Matches template specialization types.
 
 Given
@@ -1482,7 +1658,7 @@ 

Node Matchers

-Matcher<Type>templateTypeParmTypeMatcher<TemplateTypeParmType>... +Matcher<Type>templateTypeParmTypeMatcher<TemplateTypeParmType>...
Matches template type parameter types.
 
 Example matches T, but not int.
@@ -1491,12 +1667,12 @@ 

Node Matchers

-Matcher<Type>typeMatcher<Type>... +Matcher<Type>typeMatcher<Type>...
Matches Types in the clang AST.
 
-Matcher<Type>typedefTypeMatcher<TypedefType>... +Matcher<Type>typedefTypeMatcher<TypedefType>...
Matches typedef types.
 
 Given
@@ -1506,7 +1682,7 @@ 

Node Matchers

-Matcher<Type>unaryTransformTypeMatcher<UnaryTransformType>... +Matcher<Type>unaryTransformTypeMatcher<UnaryTransformType>...
Matches types nodes representing unary type transformations.
 
 Given:
@@ -1516,7 +1692,7 @@ 

Node Matchers

-Matcher<Type>variableArrayTypeMatcher<VariableArrayType>... +Matcher<Type>variableArrayTypeMatcher<VariableArrayType>...
Matches C arrays with a specified size that is not an
 integer-constant-expression.
 
@@ -1588,7 +1764,7 @@ 

Narrowing Matchers

-Matcher<BinaryOperator>hasOperatorNamestd::string Name +Matcher<BinaryOperator>hasOperatorNamestd::string Name
Matches the operator Name of operator expressions (binary or
 unary).
 
@@ -1603,12 +1779,12 @@ 

Narrowing Matchers

Example matches true (matcher = cxxBoolLiteral(equals(true))) true -Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>, - Matcher<FloatingLiteral>, Matcher<IntegerLiteral> +Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>, + Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
-Matcher<CXXCatchStmt>isCatchAll +Matcher<CXXCatchStmt>isCatchAll
Matches a C++ catch statement that has a catch-all handler.
 
 Given
@@ -1624,7 +1800,7 @@ 

Narrowing Matchers

-Matcher<CXXConstructExpr>argumentCountIsunsigned N +Matcher<CXXConstructExpr>argumentCountIsunsigned N
Checks that a call expression or a constructor call expression has
 a specific number of arguments (including absent default arguments).
 
@@ -1634,12 +1810,26 @@ 

Narrowing Matchers

-Matcher<CXXConstructExpr>isListInitialization +Matcher<CXXConstructExpr>isListInitialization
Matches a constructor call expression which uses list initialization.
 
-Matcher<CXXConstructorDecl>isCopyConstructor +Matcher<CXXConstructExpr>requiresZeroInitialization +
Matches a constructor call expression which requires
+zero initialization.
+
+Given
+void foo() {
+  struct point { double x; double y; };
+  point pt[2] = { { 1.0, 2.0 } };
+}
+initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
+will match the implicit array filler for pt[1].
+
+ + +Matcher<CXXConstructorDecl>isCopyConstructor
Matches constructor declarations that are copy constructors.
 
 Given
@@ -1652,7 +1842,7 @@ 

Narrowing Matchers

-Matcher<CXXConstructorDecl>isDefaultConstructor +Matcher<CXXConstructorDecl>isDefaultConstructor
Matches constructor declarations that are default constructors.
 
 Given
@@ -1665,7 +1855,22 @@ 

Narrowing Matchers

-Matcher<CXXConstructorDecl>isExplicit +Matcher<CXXConstructorDecl>isDelegatingConstructor +
Matches constructors that delegate to another constructor.
+
+Given
+  struct S {
+    S(); #1
+    S(int) {} #2
+    S(S &&) : S() {} #3
+  };
+  S::S() : S(0) {} #4
+cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not
+#1 or #2.
+
+ + +Matcher<CXXConstructorDecl>isExplicit
Matches constructor and conversion declarations that are marked with
 the explicit keyword.
 
@@ -1681,7 +1886,7 @@ 

Narrowing Matchers

-Matcher<CXXConstructorDecl>isMoveConstructor +Matcher<CXXConstructorDecl>isMoveConstructor
Matches constructor declarations that are move constructors.
 
 Given
@@ -1694,7 +1899,7 @@ 

Narrowing Matchers

-Matcher<CXXConversionDecl>isExplicit +Matcher<CXXConversionDecl>isExplicit
Matches constructor and conversion declarations that are marked with
 the explicit keyword.
 
@@ -1710,7 +1915,7 @@ 

Narrowing Matchers

-Matcher<CXXCtorInitializer>isBaseInitializer +Matcher<CXXCtorInitializer>isBaseInitializer
Matches a constructor initializer if it is initializing a base, as
 opposed to a member.
 
@@ -1728,7 +1933,7 @@ 

Narrowing Matchers

-Matcher<CXXCtorInitializer>isMemberInitializer +Matcher<CXXCtorInitializer>isMemberInitializer
Matches a constructor initializer if it is initializing a member, as
 opposed to a base.
 
@@ -1746,7 +1951,7 @@ 

Narrowing Matchers

-Matcher<CXXCtorInitializer>isWritten +Matcher<CXXCtorInitializer>isWritten
Matches a constructor initializer if it is explicitly written in
 code (as opposed to implicitly added by the compiler).
 
@@ -1761,7 +1966,7 @@ 

Narrowing Matchers

-Matcher<CXXMethodDecl>isConst +Matcher<CXXMethodDecl>isConst
Matches if the given method declaration is const.
 
 Given
@@ -1774,7 +1979,7 @@ 

Narrowing Matchers

-Matcher<CXXMethodDecl>isCopyAssignmentOperator +Matcher<CXXMethodDecl>isCopyAssignmentOperator
Matches if the given method declaration declares a copy assignment
 operator.
 
@@ -1789,7 +1994,7 @@ 

Narrowing Matchers

-Matcher<CXXMethodDecl>isFinal +Matcher<CXXMethodDecl>isFinal
Matches if the given method or class declaration is final.
 
 Given:
@@ -1806,7 +2011,22 @@ 

Narrowing Matchers

-Matcher<CXXMethodDecl>isOverride +Matcher<CXXMethodDecl>isMoveAssignmentOperator +
Matches if the given method declaration declares a move assignment
+operator.
+
+Given
+struct A {
+  A &operator=(const A &);
+  A &operator=(A &&);
+};
+
+cxxMethodDecl(isMoveAssignmentOperator()) matches the second method but not
+the first one.
+
+ + +Matcher<CXXMethodDecl>isOverride
Matches if the given method declaration overrides another method.
 
 Given
@@ -1822,7 +2042,7 @@ 

Narrowing Matchers

-Matcher<CXXMethodDecl>isPure +Matcher<CXXMethodDecl>isPure
Matches if the given method declaration is pure.
 
 Given
@@ -1834,7 +2054,20 @@ 

Narrowing Matchers

-Matcher<CXXMethodDecl>isVirtual +Matcher<CXXMethodDecl>isUserProvided +
Matches method declarations that are user-provided.
+
+Given
+  struct S {
+    S(); #1
+    S(const S &) = default; #2
+    S(S &&) = delete; #3
+  };
+cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3.
+
+ + +Matcher<CXXMethodDecl>isVirtual
Matches if the given method declaration is virtual.
 
 Given
@@ -1846,7 +2079,23 @@ 

Narrowing Matchers

-Matcher<CXXOperatorCallExpr>hasOverloadedOperatorNameStringRef Name +Matcher<CXXMethodDecl>isVirtualAsWritten +
Matches if the given method declaration has an explicit "virtual".
+
+Given
+  class A {
+   public:
+    virtual void x();
+  };
+  class B : public A {
+   public:
+    void x();
+  };
+  matches A::x but not B::x
+
+ + +Matcher<CXXOperatorCallExpr>hasOverloadedOperatorNameStringRef Name
Matches overloaded operator names.
 
 Matches overloaded operator names specified in strings without the
@@ -1863,16 +2112,16 @@ 

Narrowing Matchers

cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches the declaration of A. -Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl> +Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
-Matcher<CXXRecordDecl>isDerivedFromstd::string BaseName +Matcher<CXXRecordDecl>isDerivedFromstd::string BaseName
Overloaded method as shortcut for isDerivedFrom(hasName(...)).
 
-Matcher<CXXRecordDecl>isExplicitTemplateSpecialization +Matcher<CXXRecordDecl>isExplicitTemplateSpecialization
Matches explicit template specializations of function, class, or
 static member variable template instantiations.
 
@@ -1882,11 +2131,11 @@ 

Narrowing Matchers

functionDecl(isExplicitTemplateSpecialization()) matches the specialization A<int>(). -Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-Matcher<CXXRecordDecl>isFinal +Matcher<CXXRecordDecl>isFinal
Matches if the given method or class declaration is final.
 
 Given:
@@ -1903,13 +2152,24 @@ 

Narrowing Matchers

-Matcher<CXXRecordDecl>isSameOrDerivedFromstd::string BaseName +Matcher<CXXRecordDecl>isLambda +
Matches the generated class of lambda expressions.
+
+Given:
+  auto x = []{};
+
+cxxRecordDecl(isLambda()) matches the implicit class declaration of
+decltype(x)
+
+ + +Matcher<CXXRecordDecl>isSameOrDerivedFromstd::string BaseName
Overloaded method as shortcut for
 isSameOrDerivedFrom(hasName(...)).
 
-Matcher<CXXRecordDecl>isTemplateInstantiation +Matcher<CXXRecordDecl>isTemplateInstantiation
Matches template instantiations of function, class, or static
 member variable template instantiations.
 
@@ -1926,11 +2186,11 @@ 

Narrowing Matchers

cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) does not match, as X<A> is an explicit template specialization. -Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-Matcher<CallExpr>argumentCountIsunsigned N +Matcher<CallExpr>argumentCountIsunsigned N
Checks that a call expression or a constructor call expression has
 a specific number of arguments (including absent default arguments).
 
@@ -1940,18 +2200,27 @@ 

Narrowing Matchers

-Matcher<CharacterLiteral>equalsValueT Value +Matcher<CastExpr>hasCastKindCastKind Kind +
Matches casts that has a given cast kind.
+
+Example: matches the implicit cast around 0
+(matcher = castExpr(hasCastKind(CK_NullToPointer)))
+  int *p = 0;
+
+ + +Matcher<CharacterLiteral>equalsValueT Value
Matches literals that are equal to the given value.
 
 Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
-Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
-           Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
+Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
+           Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
 
-Matcher<ClassTemplateSpecializationDecl>templateArgumentCountIsunsigned N +Matcher<ClassTemplateSpecializationDecl>templateArgumentCountIsunsigned N
Matches if the number of template arguments equals N.
 
 Given
@@ -1962,7 +2231,7 @@ 

Narrowing Matchers

-Matcher<CompoundStmt>statementCountIsunsigned N +Matcher<CompoundStmt>statementCountIsunsigned N
Checks that a compound statement contains a specific number of
 child statements.
 
@@ -1974,19 +2243,24 @@ 

Narrowing Matchers

-Matcher<ConstantArrayType>hasSizeunsigned N -
Matches ConstantArrayType nodes that have the specified size.
+Matcher<ConstantArrayType>hasSizeunsigned N
+
Matches nodes that have the specified size.
 
 Given
   int a[42];
   int b[2 * 21];
   int c[41], d[43];
+  char *s = "abcd";
+  wchar_t *ws = L"abcd";
+  char *w = "a";
 constantArrayType(hasSize(42))
   matches "int a[42]" and "int b[2 * 21]"
+stringLiteral(hasSize(4))
+  matches "abcd", L"abcd"
 
-Matcher<DeclStmt>declCountIsunsigned N +Matcher<DeclStmt>declCountIsunsigned N
Matches declaration statements that contain a specific number of
 declarations.
 
@@ -1999,7 +2273,7 @@ 

Narrowing Matchers

-Matcher<Decl>equalsBoundNodestd::string ID +Matcher<Decl>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
 Matches a node if it equals the node previously bound to ID.
@@ -2022,7 +2296,14 @@ 

Narrowing Matchers

-Matcher<Decl>hasAttrattr::Kind AttrKind +Matcher<Decl>equalsNodeconst Decl* Other +
Matches if a node equals another node.
+
+Decl has pointer identity in the AST.
+
+ + +Matcher<Decl>hasAttrattr::Kind AttrKind
Matches declaration that has a given attribute.
 
 Given
@@ -2033,7 +2314,7 @@ 

Narrowing Matchers

-Matcher<Decl>isExpansionInFileMatchingstd::string RegExp +Matcher<Decl>isExpansionInFileMatchingstd::string RegExp
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -2044,11 +2325,11 @@ 

Narrowing Matchers

ASTMatcher.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<Decl>isExpansionInMainFile +Matcher<Decl>isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
 
 Example matches X but not Y
@@ -2058,11 +2339,11 @@ 

Narrowing Matchers

Y.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<Decl>isExpansionInSystemHeader +Matcher<Decl>isExpansionInSystemHeader
Matches AST nodes that were expanded within system-header-files.
 
 Example matches Y but not X
@@ -2072,17 +2353,17 @@ 

Narrowing Matchers

SystemHeader.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<Decl>isImplicit +Matcher<Decl>isImplicit
Matches a declaration that has been implicitly added
 by the compiler (eg. implicit defaultcopy constructors).
 
-Matcher<Decl>isPrivate +Matcher<Decl>isPrivate
Matches private C++ declarations.
 
 Given
@@ -2092,11 +2373,11 @@ 

Narrowing Matchers

private: int c; }; fieldDecl(isPrivate()) - matches 'int c;' + matches 'int c;'
-Matcher<Decl>isProtected +Matcher<Decl>isProtected
Matches protected C++ declarations.
 
 Given
@@ -2106,11 +2387,11 @@ 

Narrowing Matchers

private: int c; }; fieldDecl(isProtected()) - matches 'int b;' + matches 'int b;'
-Matcher<Decl>isPublic +Matcher<Decl>isPublic
Matches public C++ declarations.
 
 Given
@@ -2120,22 +2401,79 @@ 

Narrowing Matchers

private: int c; }; fieldDecl(isPublic()) - matches 'int a;' + matches 'int a;' +
+ + +Matcher<DesignatedInitExpr>designatorCountIsunsigned N +
Matches designated initializer expressions that contain
+a specific number of designators.
+
+Example: Given
+  point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
+  point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 };
+designatorCountIs(2)
+  matches '{ [2].y = 1.0, [0].x = 1.0 }',
+  but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'.
+
+ + +Matcher<FieldDecl>hasBitWidthunsigned Width +
Matches non-static data members that are bit-fields.
+
+Given
+  class C {
+    int a : 2;
+    int b : 4;
+    int c : 2;
+  };
+fieldDecl(isBitField())
+  matches 'int a;' and 'int c;' but not 'int b;'.
+
+ + +Matcher<FieldDecl>isBitField +
Matches non-static data members that are bit-fields.
+
+Given
+  class C {
+    int a : 2;
+    int b;
+  };
+fieldDecl(isBitField())
+  matches 'int a;' but not 'int b;'.
 
-Matcher<FloatingLiteral>equalsValueT Value +Matcher<FloatingLiteral>equalsValueT Value
Matches literals that are equal to the given value.
 
 Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
-Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
-           Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
+Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
+           Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
 
-Matcher<FunctionDecl>hasOverloadedOperatorNameStringRef Name +Matcher<FunctionDecl>hasDynamicExceptionSpec +
Matches functions that have a dynamic exception specification.
+
+Given:
+  void f();
+  void g() noexcept;
+  void h() noexcept(true);
+  void i() noexcept(false);
+  void j() throw();
+  void k() throw(int);
+  void l() throw(...);
+functionDecl(hasDynamicExceptionSpec()) and
+  functionProtoType(hasDynamicExceptionSpec())
+  match the declarations of j, k, and l, but not f, g, h, or i.
+
+ + +Matcher<FunctionDecl>hasOverloadedOperatorNameStringRef Name
Matches overloaded operator names.
 
 Matches overloaded operator names specified in strings without the
@@ -2152,11 +2490,11 @@ 

Narrowing Matchers

cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches the declaration of A. -Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl> +Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
-Matcher<FunctionDecl>isConstexpr +Matcher<FunctionDecl>isConstexpr
Matches constexpr variable and function declarations.
 
 Given:
@@ -2169,7 +2507,18 @@ 

Narrowing Matchers

-Matcher<FunctionDecl>isDefinition +Matcher<FunctionDecl>isDefaulted +
Matches defaulted function declarations.
+
+Given:
+  class A { ~A(); };
+  class B { ~B() = default; };
+functionDecl(isDefaulted())
+  matches the declaration of ~B, but not ~A.
+
+ + +Matcher<FunctionDecl>isDefinition
Matches if a declaration has a body attached.
 
 Example matches A, va, fa
@@ -2180,11 +2529,11 @@ 

Narrowing Matchers

void fa() {} void fb(); Doesn't match, as it has no body. -Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> +Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
-Matcher<FunctionDecl>isDeleted +Matcher<FunctionDecl>isDeleted
Matches deleted function declarations.
 
 Given:
@@ -2195,7 +2544,7 @@ 

Narrowing Matchers

-Matcher<FunctionDecl>isExplicitTemplateSpecialization +Matcher<FunctionDecl>isExplicitTemplateSpecialization
Matches explicit template specializations of function, class, or
 static member variable template instantiations.
 
@@ -2205,11 +2554,11 @@ 

Narrowing Matchers

functionDecl(isExplicitTemplateSpecialization()) matches the specialization A<int>(). -Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-Matcher<FunctionDecl>isExternC +Matcher<FunctionDecl>isExternC
Matches extern "C" function declarations.
 
 Given:
@@ -2221,7 +2570,7 @@ 

Narrowing Matchers

-Matcher<FunctionDecl>isInline +Matcher<FunctionDecl>isInline
Matches function and namespace declarations that are marked with
 the inline keyword.
 
@@ -2236,7 +2585,7 @@ 

Narrowing Matchers

-Matcher<FunctionDecl>isNoThrow +Matcher<FunctionDecl>isNoThrow
Matches functions that have a non-throwing exception specification.
 
 Given:
@@ -2245,12 +2594,12 @@ 

Narrowing Matchers

void h() throw(); void i() throw(int); void j() noexcept(false); -functionDecl(isNoThrow()) - matches the declarations of g, and h, but not f, i or j. +functionDecl(isNoThrow()) and functionProtoType(isNoThrow()) + match the declarations of g, and h, but not f, i or j.
-Matcher<FunctionDecl>isTemplateInstantiation +Matcher<FunctionDecl>isTemplateInstantiation
Matches template instantiations of function, class, or static
 member variable template instantiations.
 
@@ -2267,11 +2616,11 @@ 

Narrowing Matchers

cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) does not match, as X<A> is an explicit template specialization. -Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-Matcher<FunctionDecl>isVariadic +Matcher<FunctionDecl>isVariadic
Matches if a function declaration is variadic.
 
 Example matches f, but not g or h. The function i will not match, even when
@@ -2283,29 +2632,87 @@ 

Narrowing Matchers

-Matcher<FunctionDecl>parameterCountIsunsigned N -
Matches FunctionDecls that have a specific parameter count.
+Matcher<FunctionDecl>parameterCountIsunsigned N
+
Matches FunctionDecls and FunctionProtoTypes that have a
+specific parameter count.
 
 Given
   void f(int i) {}
   void g(int i, int j) {}
+  void h(int i, int j);
+  void j(int i);
+  void k(int x, int y, int z, ...);
 functionDecl(parameterCountIs(2))
-  matches g(int i, int j) {}
+  matches void g(int i, int j) {}
+functionProtoType(parameterCountIs(2))
+  matches void h(int i, int j)
+functionProtoType(parameterCountIs(3))
+  matches void k(int x, int y, int z, ...);
+
+ + +Matcher<FunctionProtoType>hasDynamicExceptionSpec +
Matches functions that have a dynamic exception specification.
+
+Given:
+  void f();
+  void g() noexcept;
+  void h() noexcept(true);
+  void i() noexcept(false);
+  void j() throw();
+  void k() throw(int);
+  void l() throw(...);
+functionDecl(hasDynamicExceptionSpec()) and
+  functionProtoType(hasDynamicExceptionSpec())
+  match the declarations of j, k, and l, but not f, g, h, or i.
 
-Matcher<IntegerLiteral>equalsValueT Value +Matcher<FunctionProtoType>isNoThrow +
Matches functions that have a non-throwing exception specification.
+
+Given:
+  void f();
+  void g() noexcept;
+  void h() throw();
+  void i() throw(int);
+  void j() noexcept(false);
+functionDecl(isNoThrow()) and functionProtoType(isNoThrow())
+  match the declarations of g, and h, but not f, i or j.
+
+ + +Matcher<FunctionProtoType>parameterCountIsunsigned N +
Matches FunctionDecls and FunctionProtoTypes that have a
+specific parameter count.
+
+Given
+  void f(int i) {}
+  void g(int i, int j) {}
+  void h(int i, int j);
+  void j(int i);
+  void k(int x, int y, int z, ...);
+functionDecl(parameterCountIs(2))
+  matches void g(int i, int j) {}
+functionProtoType(parameterCountIs(2))
+  matches void h(int i, int j)
+functionProtoType(parameterCountIs(3))
+  matches void k(int x, int y, int z, ...);
+
+ + +Matcher<IntegerLiteral>equalsValueT Value
Matches literals that are equal to the given value.
 
 Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
-Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
-           Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
+Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
+           Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
 
-Matcher<MemberExpr>isArrow +Matcher<MemberExpr>isArrow
Matches member expressions that are called with '->' as opposed
 to '.'.
 
@@ -2322,7 +2729,7 @@ 

Narrowing Matchers

-Matcher<NamedDecl>hasNamestd::string Name +Matcher<NamedDecl>hasNamestd::string Name
Matches NamedDecl nodes that have the specified name.
 
 Supports specifying enclosing namespaces or classes by prefixing the name
@@ -2337,7 +2744,7 @@ 

Narrowing Matchers

-Matcher<NamedDecl>matchesNamestd::string RegExp +Matcher<NamedDecl>matchesNamestd::string RegExp
Matches NamedDecl nodes whose fully qualified names contain
 a substring matched by the given RegExp.
 
@@ -2353,7 +2760,7 @@ 

Narrowing Matchers

-Matcher<NamespaceDecl>isAnonymous +Matcher<NamespaceDecl>isAnonymous
Matches anonymous namespace declarations.
 
 Given
@@ -2364,7 +2771,7 @@ 

Narrowing Matchers

-Matcher<NamespaceDecl>isInline +Matcher<NamespaceDecl>isInline
Matches function and namespace declarations that are marked with
 the inline keyword.
 
@@ -2379,7 +2786,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>argumentCountIsunsigned N +Matcher<ObjCMessageExpr>argumentCountIsunsigned N
Checks that a call expression or a constructor call expression has
 a specific number of arguments (including absent default arguments).
 
@@ -2389,7 +2796,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>hasKeywordSelector +Matcher<ObjCMessageExpr>hasKeywordSelector
Matches when the selector is a keyword selector
 
 objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
@@ -2403,7 +2810,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>hasNullSelector +Matcher<ObjCMessageExpr>hasNullSelector
Matches when the selector is the empty selector
 
 Matches only when the selector of the objCMessageExpr is NULL. This may
@@ -2411,7 +2818,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>hasSelectorstd::string BaseName +Matcher<ObjCMessageExpr>hasSelectorstd::string BaseName
Matches when BaseName == Selector.getAsString()
 
  matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
@@ -2421,7 +2828,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>hasUnarySelector +Matcher<ObjCMessageExpr>hasUnarySelector
Matches when the selector is a Unary Selector
 
  matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
@@ -2431,7 +2838,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>matchesSelectorstd::string RegExp +Matcher<ObjCMessageExpr>matchesSelectorstd::string RegExp
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
@@ -2440,7 +2847,7 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>numSelectorArgsunsigned N +Matcher<ObjCMessageExpr>numSelectorArgsunsigned N
Matches when the selector has the specified number of arguments
 
  matcher = objCMessageExpr(numSelectorArgs(0));
@@ -2453,7 +2860,7 @@ 

Narrowing Matchers

-Matcher<QualType>asStringstd::string Name +Matcher<QualType>asStringstd::string Name
Matches if the matched type is represented by the given string.
 
 Given
@@ -2464,7 +2871,7 @@ 

Narrowing Matchers

-Matcher<QualType>equalsBoundNodestd::string ID +Matcher<QualType>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
 Matches a node if it equals the node previously bound to ID.
@@ -2487,7 +2894,7 @@ 

Narrowing Matchers

-Matcher<QualType>hasLocalQualifiers +Matcher<QualType>hasLocalQualifiers
Matches QualType nodes that have local CV-qualifiers attached to
 the node, not hidden within a typedef.
 
@@ -2502,7 +2909,7 @@ 

Narrowing Matchers

-Matcher<QualType>isAnyCharacter +Matcher<QualType>isAnyCharacter
Matches QualType nodes that are of character type.
 
 Given
@@ -2514,7 +2921,25 @@ 

Narrowing Matchers

-Matcher<QualType>isConstQualified +Matcher<QualType>isAnyPointer +
Matches QualType nodes that are of any pointer type; this includes
+the Objective-C object pointer type, which is different despite being
+syntactically similar.
+
+Given
+  int *i = nullptr;
+
+  @interface Foo
+  @end
+  Foo *f;
+
+  int j;
+varDecl(hasType(isAnyPointer()))
+  matches "int *i" and "Foo *f", but not "int j".
+
+ + +Matcher<QualType>isConstQualified
Matches QualType nodes that are const-qualified, i.e., that
 include "top-level" const.
 
@@ -2531,7 +2956,7 @@ 

Narrowing Matchers

-Matcher<QualType>isInteger +Matcher<QualType>isInteger
Matches QualType nodes that are of integer type.
 
 Given
@@ -2543,7 +2968,31 @@ 

Narrowing Matchers

-Matcher<QualType>isVolatileQualified +Matcher<QualType>isSignedInteger +
Matches QualType nodes that are of signed integer type.
+
+Given
+  void a(int);
+  void b(unsigned long);
+  void c(double);
+functionDecl(hasAnyParameter(hasType(isInteger())))
+matches "a(int)", but not "b(unsigned long)" and "c(double)".
+
+ + +Matcher<QualType>isUnsignedInteger +
Matches QualType nodes that are of unsigned integer type.
+
+Given
+  void a(int);
+  void b(unsigned long);
+  void c(double);
+functionDecl(hasAnyParameter(hasType(isInteger())))
+matches "b(unsigned long)", but not "a(int)" and "c(double)".
+
+ + +Matcher<QualType>isVolatileQualified
Matches QualType nodes that are volatile-qualified, i.e., that
 include "top-level" volatile.
 
@@ -2560,7 +3009,7 @@ 

Narrowing Matchers

-Matcher<RecordDecl>isClass +Matcher<RecordDecl>isClass
Matches RecordDecl object that are spelled with "class."
 
 Example matches C, but not S or U.
@@ -2570,7 +3019,7 @@ 

Narrowing Matchers

-Matcher<RecordDecl>isStruct +Matcher<RecordDecl>isStruct
Matches RecordDecl object that are spelled with "struct."
 
 Example matches S, but not C or U.
@@ -2580,7 +3029,7 @@ 

Narrowing Matchers

-Matcher<RecordDecl>isUnion +Matcher<RecordDecl>isUnion
Matches RecordDecl object that are spelled with "union."
 
 Example matches U, but not C or S.
@@ -2590,7 +3039,7 @@ 

Narrowing Matchers

-Matcher<Stmt>equalsBoundNodestd::string ID +Matcher<Stmt>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
 Matches a node if it equals the node previously bound to ID.
@@ -2613,7 +3062,14 @@ 

Narrowing Matchers

-Matcher<Stmt>isExpansionInFileMatchingstd::string RegExp +Matcher<Stmt>equalsNodeconst Stmt* Other +
Matches if a node equals another node.
+
+Stmt has pointer identity in the AST.
+
+ + +Matcher<Stmt>isExpansionInFileMatchingstd::string RegExp
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -2624,11 +3080,11 @@ 

Narrowing Matchers

ASTMatcher.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<Stmt>isExpansionInMainFile +Matcher<Stmt>isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
 
 Example matches X but not Y
@@ -2638,11 +3094,11 @@ 

Narrowing Matchers

Y.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<Stmt>isExpansionInSystemHeader +Matcher<Stmt>isExpansionInSystemHeader
Matches AST nodes that were expanded within system-header-files.
 
 Example matches Y but not X
@@ -2652,11 +3108,28 @@ 

Narrowing Matchers

SystemHeader.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<TagDecl>isDefinition +Matcher<StringLiteral>hasSizeunsigned N +
Matches nodes that have the specified size.
+
+Given
+  int a[42];
+  int b[2 * 21];
+  int c[41], d[43];
+  char *s = "abcd";
+  wchar_t *ws = L"abcd";
+  char *w = "a";
+constantArrayType(hasSize(42))
+  matches "int a[42]" and "int b[2 * 21]"
+stringLiteral(hasSize(4))
+  matches "abcd", L"abcd"
+
+ + +Matcher<TagDecl>isDefinition
Matches if a declaration has a body attached.
 
 Example matches A, va, fa
@@ -2667,11 +3140,11 @@ 

Narrowing Matchers

void fa() {} void fb(); Doesn't match, as it has no body. -Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> +Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
-Matcher<TemplateArgument>equalsIntegralValuestd::string Value +Matcher<TemplateArgument>equalsIntegralValuestd::string Value
Matches a TemplateArgument of integral type with a given value.
 
 Note that 'Value' is a string as the template argument's value is
@@ -2687,7 +3160,7 @@ 

Narrowing Matchers

-Matcher<TemplateArgument>isIntegral +Matcher<TemplateArgument>isIntegral
Matches a TemplateArgument that is an integral value.
 
 Given
@@ -2700,7 +3173,7 @@ 

Narrowing Matchers

-Matcher<TemplateSpecializationType>templateArgumentCountIsunsigned N +Matcher<TemplateSpecializationType>templateArgumentCountIsunsigned N
Matches if the number of template arguments equals N.
 
 Given
@@ -2711,7 +3184,7 @@ 

Narrowing Matchers

-Matcher<TypeLoc>isExpansionInFileMatchingstd::string RegExp +Matcher<TypeLoc>isExpansionInFileMatchingstd::string RegExp
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -2722,11 +3195,11 @@ 

Narrowing Matchers

ASTMatcher.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<TypeLoc>isExpansionInMainFile +Matcher<TypeLoc>isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
 
 Example matches X but not Y
@@ -2736,11 +3209,11 @@ 

Narrowing Matchers

Y.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<TypeLoc>isExpansionInSystemHeader +Matcher<TypeLoc>isExpansionInSystemHeader
Matches AST nodes that were expanded within system-header-files.
 
 Example matches Y but not X
@@ -2750,11 +3223,11 @@ 

Narrowing Matchers

SystemHeader.h: class Y {}; -Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> +Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
-Matcher<Type>booleanType +Matcher<Type>booleanType
Matches type bool.
 
 Given
@@ -2764,7 +3237,7 @@ 

Narrowing Matchers

-Matcher<Type>equalsBoundNodestd::string ID +Matcher<Type>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
 Matches a node if it equals the node previously bound to ID.
@@ -2787,7 +3260,25 @@ 

Narrowing Matchers

-Matcher<Type>voidType +Matcher<Type>equalsNodeconst Type* Other +
Matches if a node equals another node.
+
+Type has pointer identity in the AST.
+
+ + +Matcher<Type>realFloatingPointType +
Matches any real floating-point type (float, double, long double).
+
+Given
+  int i;
+  float f;
+realFloatingPointType()
+  matches "float f" but not "int i"
+
+ + +Matcher<Type>voidType
Matches type void.
 
 Given
@@ -2797,7 +3288,7 @@ 

Narrowing Matchers

-Matcher<UnaryExprOrTypeTraitExpr>ofKindUnaryExprOrTypeTrait Kind +Matcher<UnaryExprOrTypeTraitExpr>ofKindUnaryExprOrTypeTrait Kind
Matches unary expressions of a certain kind.
 
 Given
@@ -2808,7 +3299,7 @@ 

Narrowing Matchers

-Matcher<UnaryOperator>hasOperatorNamestd::string Name +Matcher<UnaryOperator>hasOperatorNamestd::string Name
Matches the operator Name of operator expressions (binary or
 unary).
 
@@ -2817,7 +3308,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>hasAutomaticStorageDuration +Matcher<VarDecl>hasAutomaticStorageDuration
Matches a variable declaration that has automatic storage duration.
 
 Example matches x, but not y, z, or a.
@@ -2831,7 +3322,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>hasGlobalStorage +Matcher<VarDecl>hasGlobalStorage
Matches a variable declaration that does not have local storage.
 
 Example matches y and z (matcher = varDecl(hasGlobalStorage())
@@ -2843,7 +3334,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>hasLocalStorage +Matcher<VarDecl>hasLocalStorage
Matches a variable declaration that has function scope and is a
 non-static local variable.
 
@@ -2856,7 +3347,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>hasStaticStorageDuration +Matcher<VarDecl>hasStaticStorageDuration
Matches a variable declaration that has static storage duration.
 
 Example matches y and a, but not x or z.
@@ -2870,7 +3361,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>hasThreadStorageDuration +Matcher<VarDecl>hasThreadStorageDuration
Matches a variable declaration that has thread storage duration.
 
 Example matches z, but not x, z, or a.
@@ -2884,7 +3375,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>isConstexpr +Matcher<VarDecl>isConstexpr
Matches constexpr variable and function declarations.
 
 Given:
@@ -2897,7 +3388,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>isDefinition +Matcher<VarDecl>isDefinition
Matches if a declaration has a body attached.
 
 Example matches A, va, fa
@@ -2908,11 +3399,11 @@ 

Narrowing Matchers

void fa() {} void fb(); Doesn't match, as it has no body. -Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> +Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
-Matcher<VarDecl>isExceptionVariable +Matcher<VarDecl>isExceptionVariable
Matches a variable declaration that is an exception variable from
 a C++ catch block, or an Objective-C statement.
 
@@ -2925,7 +3416,7 @@ 

Narrowing Matchers

-Matcher<VarDecl>isExplicitTemplateSpecialization +Matcher<VarDecl>isExplicitTemplateSpecialization
Matches explicit template specializations of function, class, or
 static member variable template instantiations.
 
@@ -2935,11 +3426,11 @@ 

Narrowing Matchers

functionDecl(isExplicitTemplateSpecialization()) matches the specialization A<int>(). -Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-Matcher<VarDecl>isTemplateInstantiation +Matcher<VarDecl>isTemplateInstantiation
Matches template instantiations of function, class, or static
 member variable template instantiations.
 
@@ -2956,11 +3447,11 @@ 

Narrowing Matchers

cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) does not match, as X<A> is an explicit template specialization. -Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-Matcher<internal::Matcher<Decl>>isInstantiated +Matcher<internal::Matcher<Decl>>isInstantiated
Matches declarations that are template instantiations or are inside
 template instantiations.
 
@@ -2973,7 +3464,34 @@ 

Narrowing Matchers

-Matcher<internal::Matcher<Stmt>>isInTemplateInstantiation +Matcher<internal::Matcher<Expr>>nullPointerConstant +
Matches expressions that resolve to a null pointer constant, such as
+GNU's __null, C++11's nullptr, or C's NULL macro.
+
+Given:
+  void *v1 = NULL;
+  void *v2 = nullptr;
+  void *v3 = __null; GNU extension
+  char *cp = (char *)0;
+  int *ip = 0;
+  int i = 0;
+expr(nullPointerConstant())
+  matches the initializer for v1, v2, v3, cp, and ip. Does not match the
+  initializer for i.
+
+ + +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<Stmt>>isInTemplateInstantiation
Matches statements inside of a template instantiation.
 
 Given
@@ -3112,6 +3630,10 @@ 

AST Traversal Matchers

ChildT must be an AST base type. Usable as: Any Matcher +Note that has is direct matcher, so it also matches things like implicit +casts and paren casts. If you are matching with expr then you should +probably consider using ignoringParenImpCasts like: +has(ignoringParenImpCasts(expr())).
@@ -3127,7 +3649,59 @@

AST Traversal Matchers

-Matcher<ArraySubscriptExpr>hasBaseMatcher<Expr> InnerMatcher +Matcher<AbstractConditionalOperator>hasConditionMatcher<Expr> InnerMatcher +
Matches the condition expression of an if statement, for loop,
+switch statement or conditional operator.
+
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+  if (true) {}
+
+ + +Matcher<AbstractConditionalOperator>hasFalseExpressionMatcher<Expr> InnerMatcher +
Matches the false branch expression of a conditional operator
+(binary or ternary).
+
+Example matches b
+  condition ? a : b
+  condition ?: b
+
+ + +Matcher<AbstractConditionalOperator>hasTrueExpressionMatcher<Expr> InnerMatcher +
Matches the true branch expression of a conditional operator.
+
+Example 1 (conditional ternary operator): matches a
+  condition ? a : b
+
+Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
+  condition ?: b
+
+ + +Matcher<AddrLabelExpr>hasDeclarationMatcher<Decl> InnerMatcher +
Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+
+Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
+  Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
+  Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+  Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
+  Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
+  Matcher<TypedefType>, Matcher<UnresolvedUsingType>
+
+ + +Matcher<ArraySubscriptExpr>hasBaseMatcher<Expr> InnerMatcher
Matches the base expression of an array subscript expression.
 
 Given
@@ -3139,7 +3713,7 @@ 

AST Traversal Matchers

-Matcher<ArraySubscriptExpr>hasIndexMatcher<Expr> InnerMatcher +Matcher<ArraySubscriptExpr>hasIndexMatcher<Expr> InnerMatcher
Matches the index expression of an array subscript expression.
 
 Given
@@ -3150,7 +3724,7 @@ 

AST Traversal Matchers

-Matcher<ArraySubscriptExpr>hasLHSMatcher<Expr> InnerMatcher +Matcher<ArraySubscriptExpr>hasLHSMatcher<Expr> InnerMatcher
Matches the left hand side of binary operator expressions.
 
 Example matches a (matcher = binaryOperator(hasLHS()))
@@ -3158,7 +3732,7 @@ 

AST Traversal Matchers

-Matcher<ArraySubscriptExpr>hasRHSMatcher<Expr> InnerMatcher +Matcher<ArraySubscriptExpr>hasRHSMatcher<Expr> InnerMatcher
Matches the right hand side of binary operator expressions.
 
 Example matches b (matcher = binaryOperator(hasRHS()))
@@ -3166,7 +3740,7 @@ 

AST Traversal Matchers

-Matcher<ArrayTypeLoc>hasElementTypeLocMatcher<TypeLoc> +Matcher<ArrayTypeLoc>hasElementTypeLocMatcher<TypeLoc>
Matches arrays and C99 complex types that have a specific element
 type.
 
@@ -3177,11 +3751,11 @@ 

AST Traversal Matchers

arrayType(hasElementType(builtinType())) matches "int b[7]" -Usable as: Matcher<ArrayType>, Matcher<ComplexType> +Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-Matcher<ArrayType>hasElementTypeMatcher<Type> +Matcher<ArrayType>hasElementTypeMatcher<Type>
Matches arrays and C99 complex types that have a specific element
 type.
 
@@ -3192,11 +3766,11 @@ 

AST Traversal Matchers

arrayType(hasElementType(builtinType())) matches "int b[7]" -Usable as: Matcher<ArrayType>, Matcher<ComplexType> +Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-Matcher<AtomicTypeLoc>hasValueTypeLocMatcher<TypeLoc> +Matcher<AtomicTypeLoc>hasValueTypeLocMatcher<TypeLoc>
Matches atomic types with a specific value type.
 
 Given
@@ -3205,11 +3779,11 @@ 

AST Traversal Matchers

atomicType(hasValueType(isInteger())) matches "_Atomic(int) i" -Usable as: Matcher<AtomicType> +Usable as: Matcher<AtomicType>
-Matcher<AtomicType>hasValueTypeMatcher<Type> +Matcher<AtomicType>hasValueTypeMatcher<Type>
Matches atomic types with a specific value type.
 
 Given
@@ -3218,11 +3792,11 @@ 

AST Traversal Matchers

atomicType(hasValueType(isInteger())) matches "_Atomic(int) i" -Usable as: Matcher<AtomicType> +Usable as: Matcher<AtomicType>
-Matcher<AutoType>hasDeducedTypeMatcher<Type> +Matcher<AutoType>hasDeducedTypeMatcher<Type>
Matches AutoType nodes where the deduced type is a specific type.
 
 Note: There is no TypeLoc for the deduced type and thus no
@@ -3234,17 +3808,17 @@ 

AST Traversal Matchers

autoType(hasDeducedType(isInteger())) matches "auto a" -Usable as: Matcher<AutoType> +Usable as: Matcher<AutoType>
-Matcher<BinaryOperator>hasEitherOperandMatcher<Expr> InnerMatcher +Matcher<BinaryOperator>hasEitherOperandMatcher<Expr> InnerMatcher
Matches if either the left hand side or the right hand side of a
 binary operator matches.
 
-Matcher<BinaryOperator>hasLHSMatcher<Expr> InnerMatcher +Matcher<BinaryOperator>hasLHSMatcher<Expr> InnerMatcher
Matches the left hand side of binary operator expressions.
 
 Example matches a (matcher = binaryOperator(hasLHS()))
@@ -3252,7 +3826,7 @@ 

AST Traversal Matchers

-Matcher<BinaryOperator>hasRHSMatcher<Expr> InnerMatcher +Matcher<BinaryOperator>hasRHSMatcher<Expr> InnerMatcher
Matches the right hand side of binary operator expressions.
 
 Example matches b (matcher = binaryOperator(hasRHS()))
@@ -3260,7 +3834,7 @@ 

AST Traversal Matchers

-Matcher<BlockPointerTypeLoc>pointeeLocMatcher<TypeLoc> +Matcher<BlockPointerTypeLoc>pointeeLocMatcher<TypeLoc>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -3271,12 +3845,12 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<BlockPointerType>pointeeMatcher<Type> +Matcher<BlockPointerType>pointeeMatcher<Type>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -3287,12 +3861,32 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType> +
+ + +Matcher<CXXConstructExpr>forEachArgumentWithParamMatcher<Expr> ArgMatcher, Matcher<ParmVarDecl> ParamMatcher +
Matches all arguments and their respective ParmVarDecl.
+
+Given
+  void f(int i);
+  int y;
+  f(y);
+callExpr(
+  forEachArgumentWithParam(
+    declRefExpr(to(varDecl(hasName("y")))),
+    parmVarDecl(hasType(isInteger()))
+))
+  matches f(y);
+with declRefExpr(...)
+  matching int y
+and parmVarDecl(...)
+  matching int i
 
-Matcher<CXXConstructExpr>hasAnyArgumentMatcher<Expr> InnerMatcher +Matcher<CXXConstructExpr>hasAnyArgumentMatcher<Expr> InnerMatcher
Matches any argument of a call expression or a constructor call
 expression.
 
@@ -3302,15 +3896,10 @@ 

AST Traversal Matchers

matches x(1, y, 42) with hasAnyArgument(...) matching y - -FIXME: Currently this will ignore parentheses and implicit casts on -the argument before applying the inner matcher. We'll want to remove -this to allow for greater control by the user once ignoreImplicit() -has been implemented.
-Matcher<CXXConstructExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher +Matcher<CXXConstructExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher
Matches the n'th argument of a call expression or a constructor
 call expression.
 
@@ -3320,8 +3909,8 @@ 

AST Traversal Matchers

-Matcher<CXXConstructExpr>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a node if the declaration associated with that node
+Matcher<CXXConstructExpr>hasDeclarationMatcher<Decl>  InnerMatcher
+
Matches a node if the declaration associated with that node
 matches the given matcher.
 
 The associated declaration is:
@@ -3333,16 +3922,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<CXXConstructorDecl>forEachConstructorInitializerMatcher<CXXCtorInitializer> InnerMatcher +Matcher<CXXConstructorDecl>forEachConstructorInitializerMatcher<CXXCtorInitializer> InnerMatcher
Matches each constructor initializer in a constructor definition.
 
 Given
@@ -3354,7 +3943,7 @@ 

AST Traversal Matchers

-Matcher<CXXConstructorDecl>hasAnyConstructorInitializerMatcher<CXXCtorInitializer> InnerMatcher +Matcher<CXXConstructorDecl>hasAnyConstructorInitializerMatcher<CXXCtorInitializer> InnerMatcher
Matches a constructor initializer.
 
 Given
@@ -3369,7 +3958,7 @@ 

AST Traversal Matchers

-Matcher<CXXCtorInitializer>forFieldMatcher<FieldDecl> InnerMatcher +Matcher<CXXCtorInitializer>forFieldMatcher<FieldDecl> InnerMatcher
Matches the field declaration of a constructor initializer.
 
 Given
@@ -3384,7 +3973,7 @@ 

AST Traversal Matchers

-Matcher<CXXCtorInitializer>withInitializerMatcher<Expr> InnerMatcher +Matcher<CXXCtorInitializer>withInitializerMatcher<Expr> InnerMatcher
Matches the initializer expression of a constructor initializer.
 
 Given
@@ -3399,9 +3988,9 @@ 

AST Traversal Matchers

-Matcher<CXXForRangeStmt>hasBodyMatcher<Stmt> InnerMatcher -
Matches a 'for', 'while', or 'do while' statement that has
-a given body.
+Matcher<CXXForRangeStmt>hasBodyMatcher<Stmt> InnerMatcher
+
Matches a 'for', 'while', 'do while' statement or a function
+definition that has a given body.
 
 Given
   for (;;) {}
@@ -3412,7 +4001,7 @@ 

AST Traversal Matchers

-Matcher<CXXForRangeStmt>hasLoopVariableMatcher<VarDecl> InnerMatcher +Matcher<CXXForRangeStmt>hasLoopVariableMatcher<VarDecl> InnerMatcher
Matches the initialization statement of a for loop.
 
 Example:
@@ -3422,7 +4011,7 @@ 

AST Traversal Matchers

-Matcher<CXXForRangeStmt>hasRangeInitMatcher<Expr> InnerMatcher +Matcher<CXXForRangeStmt>hasRangeInitMatcher<Expr> InnerMatcher
Matches the range initialization statement of a for loop.
 
 Example:
@@ -3432,11 +4021,11 @@ 

AST Traversal Matchers

-Matcher<CXXMemberCallExpr>onImplicitObjectArgumentMatcher<Expr> InnerMatcher +Matcher<CXXMemberCallExpr>onImplicitObjectArgumentMatcher<Expr> InnerMatcher

 
 
-Matcher<CXXMemberCallExpr>onMatcher<Expr> InnerMatcher
+Matcher<CXXMemberCallExpr>onMatcher<Expr> InnerMatcher
 
Matches on the implicit object argument of a member call expression.
 
 Example matches y.x()
@@ -3448,18 +4037,42 @@ 

AST Traversal Matchers

-Matcher<CXXMemberCallExpr>thisPointerTypeMatcher<Decl> InnerMatcher +Matcher<CXXMemberCallExpr>thisPointerTypeMatcher<Decl> InnerMatcher
Overloaded to match the type's declaration.
 
-Matcher<CXXMemberCallExpr>thisPointerTypeMatcher<QualType> InnerMatcher +Matcher<CXXMemberCallExpr>thisPointerTypeMatcher<QualType> InnerMatcher
Matches if the expression's type either matches the specified
 matcher, or is a pointer to a type that matches the InnerMatcher.
 
-Matcher<CXXMethodDecl>ofClassMatcher<CXXRecordDecl> InnerMatcher +Matcher<CXXMethodDecl>forEachOverriddenMatcher<CXXMethodDecl> InnerMatcher +
Matches each method overriden by the given method. This matcher may
+produce multiple matches.
+
+Given
+  class A { virtual void f(); };
+  class B : public A { void f(); };
+  class C : public B { void f(); };
+cxxMethodDecl(ofClass(hasName("C")),
+              forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
+  matches once, with "b" binding "A::f" and "d" binding "C::f" (Note
+  that B::f is not overridden by C::f).
+
+The check can produce multiple matches in case of multiple inheritance, e.g.
+  class A1 { virtual void f(); };
+  class A2 { virtual void f(); };
+  class C : public A1, public A2 { void f(); };
+cxxMethodDecl(ofClass(hasName("C")),
+              forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
+  matches twice, once with "b" binding "A1::f" and "d" binding "C::f", and
+  once with "b" binding "A2::f" and "d" binding "C::f".
+
+ + +Matcher<CXXMethodDecl>ofClassMatcher<CXXRecordDecl> InnerMatcher
Matches the class declaration that the given method declaration
 belongs to.
 
@@ -3478,7 +4091,7 @@ 

AST Traversal Matchers

-Matcher<CXXRecordDecl>hasMethodMatcher<CXXMethodDecl> InnerMatcher +Matcher<CXXRecordDecl>hasMethodMatcher<CXXMethodDecl> InnerMatcher
Matches the first method of a class or struct that satisfies InnerMatcher.
 
 Given:
@@ -3490,7 +4103,7 @@ 

AST Traversal Matchers

-Matcher<CXXRecordDecl>isDerivedFromMatcher<NamedDecl> Base +Matcher<CXXRecordDecl>isDerivedFromMatcher<NamedDecl> Base
Matches C++ classes that are directly or indirectly derived from
 a class matching Base.
 
@@ -3511,13 +4124,13 @@ 

AST Traversal Matchers

-Matcher<CXXRecordDecl>isSameOrDerivedFromMatcher<NamedDecl> Base +Matcher<CXXRecordDecl>isSameOrDerivedFromMatcher<NamedDecl> Base
Similar to isDerivedFrom(), but also matches classes that directly
 match Base.
 
-Matcher<CallExpr>calleeMatcher<Decl> InnerMatcher +Matcher<CallExpr>calleeMatcher<Decl> InnerMatcher
Matches if the call expression's callee's declaration matches the
 given matcher.
 
@@ -3528,7 +4141,7 @@ 

AST Traversal Matchers

-Matcher<CallExpr>calleeMatcher<Stmt> InnerMatcher +Matcher<CallExpr>calleeMatcher<Stmt> InnerMatcher
Matches if the call expression's callee expression matches.
 
 Given
@@ -3539,14 +4152,34 @@ 

AST Traversal Matchers

with callee(...) matching this->x, x, y.x, f respectively -Note: Callee cannot take the more general internal::Matcher<Expr> +Note: Callee cannot take the more general internal::Matcher<Expr> because this introduces ambiguous overloads with calls to Callee taking a -internal::Matcher<Decl>, as the matcher hierarchy is purely +internal::Matcher<Decl>, as the matcher hierarchy is purely implemented in terms of implicit casts.
-Matcher<CallExpr>hasAnyArgumentMatcher<Expr> InnerMatcher +Matcher<CallExpr>forEachArgumentWithParamMatcher<Expr> ArgMatcher, Matcher<ParmVarDecl> ParamMatcher +
Matches all arguments and their respective ParmVarDecl.
+
+Given
+  void f(int i);
+  int y;
+  f(y);
+callExpr(
+  forEachArgumentWithParam(
+    declRefExpr(to(varDecl(hasName("y")))),
+    parmVarDecl(hasType(isInteger()))
+))
+  matches f(y);
+with declRefExpr(...)
+  matching int y
+and parmVarDecl(...)
+  matching int i
+
+ + +Matcher<CallExpr>hasAnyArgumentMatcher<Expr> InnerMatcher
Matches any argument of a call expression or a constructor call
 expression.
 
@@ -3556,15 +4189,10 @@ 

AST Traversal Matchers

matches x(1, y, 42) with hasAnyArgument(...) matching y - -FIXME: Currently this will ignore parentheses and implicit casts on -the argument before applying the inner matcher. We'll want to remove -this to allow for greater control by the user once ignoreImplicit() -has been implemented.
-Matcher<CallExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher +Matcher<CallExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher
Matches the n'th argument of a call expression or a constructor
 call expression.
 
@@ -3574,8 +4202,8 @@ 

AST Traversal Matchers

-Matcher<CallExpr>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a node if the declaration associated with that node
+Matcher<CallExpr>hasDeclarationMatcher<Decl>  InnerMatcher
+
Matches a node if the declaration associated with that node
 matches the given matcher.
 
 The associated declaration is:
@@ -3587,16 +4215,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<CaseStmt>hasCaseConstantMatcher<Expr> InnerMatcher +Matcher<CaseStmt>hasCaseConstantMatcher<Expr> InnerMatcher
If the given case statement does not use the GNU case range
 extension, matches the constant given in the statement.
 
@@ -3607,17 +4235,11 @@ 

AST Traversal Matchers

-Matcher<CastExpr>hasSourceExpressionMatcher<Expr> InnerMatcher -
Matches if the cast's source expression matches the given matcher.
-
-Example: matches "a string" (matcher =
-                                 hasSourceExpression(cxxConstructExpr()))
-class URL { URL(string); };
-URL url = "a string";
-
+Matcher<CastExpr>hasSourceExpressionMatcher<Expr> InnerMatcher +

 
 
-Matcher<ClassTemplateSpecializationDecl>hasAnyTemplateArgumentMatcher<TemplateArgument> InnerMatcher
+Matcher<ClassTemplateSpecializationDecl>hasAnyTemplateArgumentMatcher<TemplateArgument> InnerMatcher
 
Matches classTemplateSpecializations that have at least one
 TemplateArgument matching the given InnerMatcher.
 
@@ -3631,7 +4253,7 @@ 

AST Traversal Matchers

-Matcher<ClassTemplateSpecializationDecl>hasTemplateArgumentunsigned N, Matcher<TemplateArgument> InnerMatcher +Matcher<ClassTemplateSpecializationDecl>hasTemplateArgumentunsigned N, Matcher<TemplateArgument> InnerMatcher
Matches classTemplateSpecializations where the n'th TemplateArgument
 matches the given InnerMatcher.
 
@@ -3645,7 +4267,7 @@ 

AST Traversal Matchers

-Matcher<ComplexTypeLoc>hasElementTypeLocMatcher<TypeLoc> +Matcher<ComplexTypeLoc>hasElementTypeLocMatcher<TypeLoc>
Matches arrays and C99 complex types that have a specific element
 type.
 
@@ -3656,11 +4278,11 @@ 

AST Traversal Matchers

arrayType(hasElementType(builtinType())) matches "int b[7]" -Usable as: Matcher<ArrayType>, Matcher<ComplexType> +Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-Matcher<ComplexType>hasElementTypeMatcher<Type> +Matcher<ComplexType>hasElementTypeMatcher<Type>
Matches arrays and C99 complex types that have a specific element
 type.
 
@@ -3671,13 +4293,13 @@ 

AST Traversal Matchers

arrayType(hasElementType(builtinType())) matches "int b[7]" -Usable as: Matcher<ArrayType>, Matcher<ComplexType> +Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-Matcher<CompoundStmt>hasAnySubstatementMatcher<Stmt> InnerMatcher +Matcher<CompoundStmt>hasAnySubstatementMatcher<Stmt> InnerMatcher
Matches compound statements where at least one substatement matches
-a given matcher.
+a given matcher. Also matches StmtExprs that have CompoundStmt as children.
 
 Given
   { {}; 1+2; }
@@ -3688,38 +4310,13 @@ 

AST Traversal Matchers

-Matcher<ConditionalOperator>hasConditionMatcher<Expr> InnerMatcher -
Matches the condition expression of an if statement, for loop,
-or conditional operator.
-
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
-  if (true) {}
-
- - -Matcher<ConditionalOperator>hasFalseExpressionMatcher<Expr> InnerMatcher -
Matches the false branch expression of a conditional operator.
-
-Example matches b
-  condition ? a : b
-
- - -Matcher<ConditionalOperator>hasTrueExpressionMatcher<Expr> InnerMatcher -
Matches the true branch expression of a conditional operator.
-
-Example matches a
-  condition ? a : b
-
- - -Matcher<DecayedType>hasDecayedTypeMatcher<QualType> InnerType +Matcher<DecayedType>hasDecayedTypeMatcher<QualType> InnerType
Matches the decayed type, whos decayed type matches InnerMatcher
 
-Matcher<DeclRefExpr>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a node if the declaration associated with that node
+Matcher<DeclRefExpr>hasDeclarationMatcher<Decl>  InnerMatcher
+
Matches a node if the declaration associated with that node
 matches the given matcher.
 
 The associated declaration is:
@@ -3731,16 +4328,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<DeclRefExpr>throughUsingDeclMatcher<UsingShadowDecl> InnerMatcher +Matcher<DeclRefExpr>throughUsingDeclMatcher<UsingShadowDecl> InnerMatcher
Matches a DeclRefExpr that refers to a declaration through a
 specific using shadow declaration.
 
@@ -3756,7 +4353,7 @@ 

AST Traversal Matchers

-Matcher<DeclRefExpr>toMatcher<Decl> InnerMatcher +Matcher<DeclRefExpr>toMatcher<Decl> InnerMatcher
Matches a DeclRefExpr that refers to a declaration that matches the
 specified matcher.
 
@@ -3767,7 +4364,7 @@ 

AST Traversal Matchers

-Matcher<DeclStmt>containsDeclarationunsigned N, Matcher<Decl> InnerMatcher +Matcher<DeclStmt>containsDeclarationunsigned N, Matcher<Decl> InnerMatcher
Matches the n'th declaration of a declaration statement.
 
 Note that this does not work for global declarations because the AST
@@ -3786,7 +4383,7 @@ 

AST Traversal Matchers

-Matcher<DeclStmt>hasSingleDeclMatcher<Decl> InnerMatcher +Matcher<DeclStmt>hasSingleDeclMatcher<Decl> InnerMatcher
Matches the Decl of a DeclStmt which has a single declaration.
 
 Given
@@ -3797,7 +4394,7 @@ 

AST Traversal Matchers

-Matcher<DeclaratorDecl>hasTypeLocMatcher<TypeLoc> Inner +Matcher<DeclaratorDecl>hasTypeLocMatcher<TypeLoc> Inner
Matches if the type location of the declarator decl's type matches
 the inner matcher.
 
@@ -3808,7 +4405,7 @@ 

AST Traversal Matchers

-Matcher<Decl>hasDeclContextMatcher<Decl> InnerMatcher +Matcher<Decl>hasDeclContextMatcher<Decl> InnerMatcher
Matches declarations whose declaration context, interpreted as a
 Decl, matches InnerMatcher.
 
@@ -3824,9 +4421,9 @@ 

AST Traversal Matchers

-Matcher<DoStmt>hasBodyMatcher<Stmt> InnerMatcher -
Matches a 'for', 'while', or 'do while' statement that has
-a given body.
+Matcher<DoStmt>hasBodyMatcher<Stmt> InnerMatcher
+
Matches a 'for', 'while', 'do while' statement or a function
+definition that has a given body.
 
 Given
   for (;;) {}
@@ -3837,16 +4434,16 @@ 

AST Traversal Matchers

-Matcher<DoStmt>hasConditionMatcher<Expr> InnerMatcher +Matcher<DoStmt>hasConditionMatcher<Expr> InnerMatcher
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
-Matcher<ElaboratedType>hasQualifierMatcher<NestedNameSpecifier> InnerMatcher +Matcher<ElaboratedType>hasQualifierMatcher<NestedNameSpecifier> InnerMatcher
Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
 matches InnerMatcher if the qualifier exists.
 
@@ -3863,7 +4460,7 @@ 

AST Traversal Matchers

-Matcher<ElaboratedType>namesTypeMatcher<QualType> InnerMatcher +Matcher<ElaboratedType>namesTypeMatcher<QualType> InnerMatcher
Matches ElaboratedTypes whose named type matches InnerMatcher.
 
 Given
@@ -3880,8 +4477,8 @@ 

AST Traversal Matchers

-Matcher<EnumType>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a node if the declaration associated with that node
+Matcher<EnumType>hasDeclarationMatcher<Decl>  InnerMatcher
+
Matches a node if the declaration associated with that node
 matches the given matcher.
 
 The associated declaration is:
@@ -3893,16 +4490,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<ExplicitCastExpr>hasDestinationTypeMatcher<QualType> InnerMatcher +Matcher<ExplicitCastExpr>hasDestinationTypeMatcher<QualType> InnerMatcher
Matches casts whose destination type matches a given matcher.
 
 (Note: Clang's AST refers to other conversions as "casts" too, and calls
@@ -3910,8 +4507,8 @@ 

AST Traversal Matchers

-Matcher<Expr>hasTypeMatcher<Decl> InnerMatcher -
Overloaded to match the declaration of the expression's or value
+Matcher<Expr>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),
@@ -3925,22 +4522,24 @@ 

AST Traversal Matchers

class X {}; void y(X &x) { x; X z; } -Usable as: Matcher<Expr>, Matcher<ValueDecl> +Usable as: Matcher<Expr>, Matcher<ValueDecl>
-Matcher<Expr>hasTypeMatcher<QualType> InnerMatcher +Matcher<Expr>hasTypeMatcher<QualType> InnerMatcher
Matches if the expression's or declaration's type matches a type
 matcher.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and U (matcher = typedefDecl(hasType(asString("int")))
  class X {};
  void y(X &x) { x; X z; }
+ typedef int U;
 
-Matcher<Expr>ignoringImpCastsMatcher<Expr> InnerMatcher +Matcher<Expr>ignoringImpCastsMatcher<Expr> InnerMatcher
Matches expressions that match InnerMatcher after any implicit casts
 are stripped off.
 
@@ -3963,7 +4562,26 @@ 

AST Traversal Matchers

-Matcher<Expr>ignoringParenCastsMatcher<Expr> InnerMatcher +Matcher<Expr>ignoringImplicitast_matchers::Matcher<Expr> InnerMatcher +
Matches expressions that match InnerMatcher after any implicit AST
+nodes are stripped off.
+
+Parentheses and explicit casts are not discarded.
+Given
+  class C {};
+  C a = C();
+  C b;
+  C c = b;
+The matchers
+   varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr())))
+would match the declarations for a, b, and c.
+While
+   varDecl(hasInitializer(cxxConstructExpr()))
+only match the declarations for b and c.
+
+ + +Matcher<Expr>ignoringParenCastsMatcher<Expr> InnerMatcher
Matches expressions that match InnerMatcher after parentheses and
 casts are stripped off.
 
@@ -3982,7 +4600,7 @@ 

AST Traversal Matchers

-Matcher<Expr>ignoringParenImpCastsMatcher<Expr> InnerMatcher +Matcher<Expr>ignoringParenImpCastsMatcher<Expr> InnerMatcher
Matches expressions that match InnerMatcher after implicit casts and
 parentheses are stripped off.
 
@@ -4005,9 +4623,9 @@ 

AST Traversal Matchers

-Matcher<ForStmt>hasBodyMatcher<Stmt> InnerMatcher -
Matches a 'for', 'while', or 'do while' statement that has
-a given body.
+Matcher<ForStmt>hasBodyMatcher<Stmt> InnerMatcher
+
Matches a 'for', 'while', 'do while' statement or a function
+definition that has a given body.
 
 Given
   for (;;) {}
@@ -4018,16 +4636,16 @@ 

AST Traversal Matchers

-Matcher<ForStmt>hasConditionMatcher<Expr> InnerMatcher +Matcher<ForStmt>hasConditionMatcher<Expr> InnerMatcher
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
-Matcher<ForStmt>hasIncrementMatcher<Stmt> InnerMatcher +Matcher<ForStmt>hasIncrementMatcher<Stmt> InnerMatcher
Matches the increment statement of a for loop.
 
 Example:
@@ -4037,7 +4655,7 @@ 

AST Traversal Matchers

-Matcher<ForStmt>hasLoopInitMatcher<Stmt> InnerMatcher +Matcher<ForStmt>hasLoopInitMatcher<Stmt> InnerMatcher
Matches the initialization statement of a for loop.
 
 Example:
@@ -4047,7 +4665,7 @@ 

AST Traversal Matchers

-Matcher<FunctionDecl>hasAnyParameterMatcher<ParmVarDecl> InnerMatcher +Matcher<FunctionDecl>hasAnyParameterMatcher<ParmVarDecl> InnerMatcher
Matches any parameter of a function declaration.
 
 Does not match the 'this' parameter of a method.
@@ -4061,7 +4679,20 @@ 

AST Traversal Matchers

-Matcher<FunctionDecl>hasParameterunsigned N, Matcher<ParmVarDecl> InnerMatcher +Matcher<FunctionDecl>hasBodyMatcher<Stmt> InnerMatcher +
Matches a 'for', 'while', 'do while' statement or a function
+definition that has a given body.
+
+Given
+  for (;;) {}
+hasBody(compoundStmt())
+  matches 'for (;;) {}'
+with compoundStmt()
+  matching '{}'
+
+ + +Matcher<FunctionDecl>hasParameterunsigned N, Matcher<ParmVarDecl> InnerMatcher
Matches the n'th parameter of a function declaration.
 
 Given
@@ -4073,7 +4704,7 @@ 

AST Traversal Matchers

-Matcher<FunctionDecl>returnsMatcher<QualType> InnerMatcher +Matcher<FunctionDecl>returnsMatcher<QualType> InnerMatcher
Matches the return type of a function declaration.
 
 Given:
@@ -4083,16 +4714,16 @@ 

AST Traversal Matchers

-Matcher<IfStmt>hasConditionMatcher<Expr> InnerMatcher +Matcher<IfStmt>hasConditionMatcher<Expr> InnerMatcher
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
-Matcher<IfStmt>hasConditionVariableStatementMatcher<DeclStmt> InnerMatcher +Matcher<IfStmt>hasConditionVariableStatementMatcher<DeclStmt> InnerMatcher
Matches the condition variable statement in an if statement.
 
 Given
@@ -4102,7 +4733,7 @@ 

AST Traversal Matchers

-Matcher<IfStmt>hasElseMatcher<Stmt> InnerMatcher +Matcher<IfStmt>hasElseMatcher<Stmt> InnerMatcher
Matches the else-statement of an if statement.
 
 Examples matches the if statement
@@ -4111,7 +4742,7 @@ 

AST Traversal Matchers

-Matcher<IfStmt>hasThenMatcher<Stmt> InnerMatcher +Matcher<IfStmt>hasThenMatcher<Stmt> InnerMatcher
Matches the then-statement of an if statement.
 
 Examples matches the if statement
@@ -4120,7 +4751,7 @@ 

AST Traversal Matchers

-Matcher<ImplicitCastExpr>hasImplicitDestinationTypeMatcher<QualType> InnerMatcher +Matcher<ImplicitCastExpr>hasImplicitDestinationTypeMatcher<QualType> InnerMatcher
Matches implicit casts whose destination type matches a given
 matcher.
 
@@ -4128,8 +4759,14 @@ 

AST Traversal Matchers

-Matcher<InjectedClassNameType>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a node if the declaration associated with that node
+Matcher<InitListExpr>hasSyntacticFormMatcher<Expr> InnerMatcher
+
Matches the syntactic form of init list expressions
+(if expression have it).
+
+ + +Matcher<InjectedClassNameType>hasDeclarationMatcher<Decl> InnerMatcher +
Matches a node if the declaration associated with that node
 matches the given matcher.
 
 The associated declaration is:
@@ -4141,17 +4778,17 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<LabelStmt>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a node if the declaration associated with that node
+Matcher<LabelStmt>hasDeclarationMatcher<Decl>  InnerMatcher
+
Matches a node if the declaration associated with that node
 matches the given matcher.
 
 The associated declaration is:
@@ -4163,16 +4800,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<MemberExpr>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<MemberExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4185,16 +4822,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<MemberExpr>hasObjectExpressionMatcher<Expr> InnerMatcher +Matcher<MemberExpr>hasObjectExpressionMatcher<Expr> InnerMatcher
Matches a member expression where the object expression is
 matched by a given matcher.
 
@@ -4208,7 +4845,7 @@ 

AST Traversal Matchers

-Matcher<MemberExpr>memberMatcher<ValueDecl> InnerMatcher +Matcher<MemberExpr>memberMatcher<ValueDecl> InnerMatcher
Matches a member expression where the member is matched by a
 given matcher.
 
@@ -4222,7 +4859,7 @@ 

AST Traversal Matchers

-Matcher<MemberPointerTypeLoc>pointeeLocMatcher<TypeLoc> +Matcher<MemberPointerTypeLoc>pointeeLocMatcher<TypeLoc>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -4233,12 +4870,12 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<MemberPointerType>pointeeMatcher<Type> +Matcher<MemberPointerType>pointeeMatcher<Type>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -4249,12 +4886,12 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<NestedNameSpecifierLoc>hasPrefixMatcher<NestedNameSpecifierLoc> InnerMatcher +Matcher<NestedNameSpecifierLoc>hasPrefixMatcher<NestedNameSpecifierLoc> InnerMatcher
Matches on the prefix of a NestedNameSpecifierLoc.
 
 Given
@@ -4265,7 +4902,7 @@ 

AST Traversal Matchers

-Matcher<NestedNameSpecifierLoc>specifiesTypeLocMatcher<TypeLoc> InnerMatcher +Matcher<NestedNameSpecifierLoc>specifiesTypeLocMatcher<TypeLoc> InnerMatcher
Matches nested name specifier locs that specify a type matching the
 given TypeLoc.
 
@@ -4278,7 +4915,7 @@ 

AST Traversal Matchers

-Matcher<NestedNameSpecifier>hasPrefixMatcher<NestedNameSpecifier> InnerMatcher +Matcher<NestedNameSpecifier>hasPrefixMatcher<NestedNameSpecifier> InnerMatcher
Matches on the prefix of a NestedNameSpecifier.
 
 Given
@@ -4289,7 +4926,7 @@ 

AST Traversal Matchers

-Matcher<NestedNameSpecifier>specifiesNamespaceMatcher<NamespaceDecl> InnerMatcher +Matcher<NestedNameSpecifier>specifiesNamespaceMatcher<NamespaceDecl> InnerMatcher
Matches nested name specifiers that specify a namespace matching the
 given namespace matcher.
 
@@ -4301,7 +4938,7 @@ 

AST Traversal Matchers

-Matcher<NestedNameSpecifier>specifiesTypeMatcher<QualType> InnerMatcher +Matcher<NestedNameSpecifier>specifiesTypeMatcher<QualType> InnerMatcher
Matches nested name specifiers that specify a type matching the
 given QualType matcher without qualifiers.
 
@@ -4315,7 +4952,7 @@ 

AST Traversal Matchers

-Matcher<ObjCMessageExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher +Matcher<ObjCMessageExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher
Matches the n'th argument of a call expression or a constructor
 call expression.
 
@@ -4325,7 +4962,7 @@ 

AST Traversal Matchers

-Matcher<ObjCMessageExpr>hasReceiverTypeMatcher<QualType> InnerMatcher +Matcher<ObjCMessageExpr>hasReceiverTypeMatcher<QualType> InnerMatcher
Matches on the receiver of an ObjectiveC Message expression.
 
 Example
@@ -4337,7 +4974,11 @@ 

AST Traversal Matchers

-Matcher<ParenType>innerTypeMatcher<Type> +Matcher<OpaqueValueExpr>hasSourceExpressionMatcher<Expr> InnerMatcher +

+
+
+Matcher<ParenType>innerTypeMatcher<Type>
 
Matches ParenType nodes where the inner type is a specific type.
 
 Given
@@ -4347,11 +4988,11 @@ 

AST Traversal Matchers

varDecl(hasType(pointsTo(parenType(innerType(functionType()))))) matches ptr_to_func but not ptr_to_array. -Usable as: Matcher<ParenType> +Usable as: Matcher<ParenType>
-Matcher<PointerTypeLoc>pointeeLocMatcher<TypeLoc> +Matcher<PointerTypeLoc>pointeeLocMatcher<TypeLoc>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -4362,12 +5003,12 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<PointerType>pointeeMatcher<Type> +Matcher<PointerType>pointeeMatcher<Type>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -4378,12 +5019,12 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<QualType>hasCanonicalTypeMatcher<QualType> InnerMatcher +Matcher<QualType>hasCanonicalTypeMatcher<QualType> InnerMatcher
Matches QualTypes whose canonical type matches InnerMatcher.
 
 Given:
@@ -4396,7 +5037,7 @@ 

AST Traversal Matchers

-Matcher<QualType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<QualType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4409,21 +5050,32 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<QualType>pointsToMatcher<Decl> InnerMatcher +Matcher<QualType>ignoringParensMatcher<QualType> InnerMatcher +
Matches types that match InnerMatcher after any parens are stripped.
+
+Given
+  void (*fp)(void);
+The matcher
+  varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
+would match the declaration for fp.
+
+ + +Matcher<QualType>pointsToMatcher<Decl> InnerMatcher
Overloaded to match the pointee type's declaration.
 
-Matcher<QualType>pointsToMatcher<QualType> InnerMatcher +Matcher<QualType>pointsToMatcher<QualType> InnerMatcher
Matches if the matched type is a pointer type and the pointee type
 matches the specified matcher.
 
@@ -4435,12 +5087,12 @@ 

AST Traversal Matchers

-Matcher<QualType>referencesMatcher<Decl> InnerMatcher +Matcher<QualType>referencesMatcher<Decl> InnerMatcher
Overloaded to match the referenced type's declaration.
 
-Matcher<QualType>referencesMatcher<QualType> InnerMatcher +Matcher<QualType>referencesMatcher<QualType> InnerMatcher
Matches if the matched type is a reference type and the referenced
 type matches the specified matcher.
 
@@ -4455,7 +5107,7 @@ 

AST Traversal Matchers

-Matcher<RecordType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<RecordType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4468,16 +5120,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<ReferenceTypeLoc>pointeeLocMatcher<TypeLoc> +Matcher<ReferenceTypeLoc>pointeeLocMatcher<TypeLoc>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -4488,12 +5140,12 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<ReferenceType>pointeeMatcher<Type> +Matcher<ReferenceType>pointeeMatcher<Type>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
 
@@ -4504,24 +5156,63 @@ 

AST Traversal Matchers

pointerType(pointee(isConstQualified(), isInteger())) matches "int const *b" -Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, - Matcher<PointerType>, Matcher<ReferenceType> +Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, + Matcher<PointerType>, Matcher<ReferenceType>
-Matcher<Stmt>alignOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher +Matcher<ReturnStmt>hasReturnValueMatcher<Expr> InnerMatcher +
Matches the return value expression of a return statement
+
+Given
+  return a + b;
+hasReturnValue(binaryOperator())
+  matches 'return a + b'
+with binaryOperator()
+  matching 'a + b'
+
+ + +Matcher<StmtExpr>hasAnySubstatementMatcher<Stmt> InnerMatcher +
Matches compound statements where at least one substatement matches
+a given matcher. Also matches StmtExprs that have CompoundStmt as children.
+
+Given
+  { {}; 1+2; }
+hasAnySubstatement(compoundStmt())
+  matches '{ {}; 1+2; }'
+with compoundStmt()
+  matching '{}'
+
+ + +Matcher<Stmt>alignOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher
Same as unaryExprOrTypeTraitExpr, but only matching
 alignof.
 
-Matcher<Stmt>sizeOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher +Matcher<Stmt>forFunctionMatcher<FunctionDecl> InnerMatcher +
Matches declaration of the function the statemenet belongs to
+
+Given:
+F& operator=(const F& o) {
+  std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
+  return *this;
+}
+returnStmt(forFunction(hasName("operator=")))
+  matches 'return *this'
+  but does match 'return > 0'
+
+ + +Matcher<Stmt>sizeOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher
Same as unaryExprOrTypeTraitExpr, but only matching
 sizeof.
 
-Matcher<SwitchStmt>forEachSwitchCaseMatcher<SwitchCase> InnerMatcher +Matcher<SwitchStmt>forEachSwitchCaseMatcher<SwitchCase> InnerMatcher
Matches each case or default statement belonging to the given switch
 statement. This matcher may produce multiple matches.
 
@@ -4534,7 +5225,16 @@ 

AST Traversal Matchers

-Matcher<TagType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<SwitchStmt>hasConditionMatcher<Expr> InnerMatcher +
Matches the condition expression of an if statement, for loop,
+switch statement or conditional operator.
+
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+  if (true) {}
+
+ + +Matcher<TagType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4547,16 +5247,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<TemplateArgument>isExprMatcher<Expr> InnerMatcher +Matcher<TemplateArgument>isExprMatcher<Expr> InnerMatcher
Matches a sugar TemplateArgument that refers to a certain expression.
 
 Given
@@ -4570,7 +5270,7 @@ 

AST Traversal Matchers

-Matcher<TemplateArgument>refersToDeclarationMatcher<Decl> InnerMatcher +Matcher<TemplateArgument>refersToDeclarationMatcher<Decl> InnerMatcher
Matches a canonical TemplateArgument that refers to a certain
 declaration.
 
@@ -4585,7 +5285,7 @@ 

AST Traversal Matchers

-Matcher<TemplateArgument>refersToIntegralTypeMatcher<QualType> InnerMatcher +Matcher<TemplateArgument>refersToIntegralTypeMatcher<QualType> InnerMatcher
Matches a TemplateArgument that referes to an integral type.
 
 Given
@@ -4597,7 +5297,7 @@ 

AST Traversal Matchers

-Matcher<TemplateArgument>refersToTypeMatcher<QualType> InnerMatcher +Matcher<TemplateArgument>refersToTypeMatcher<QualType> InnerMatcher
Matches a TemplateArgument that refers to a certain type.
 
 Given
@@ -4610,7 +5310,7 @@ 

AST Traversal Matchers

-Matcher<TemplateSpecializationType>hasAnyTemplateArgumentMatcher<TemplateArgument> InnerMatcher +Matcher<TemplateSpecializationType>hasAnyTemplateArgumentMatcher<TemplateArgument> InnerMatcher
Matches classTemplateSpecializations that have at least one
 TemplateArgument matching the given InnerMatcher.
 
@@ -4624,7 +5324,7 @@ 

AST Traversal Matchers

-Matcher<TemplateSpecializationType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<TemplateSpecializationType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4637,16 +5337,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<TemplateSpecializationType>hasTemplateArgumentunsigned N, Matcher<TemplateArgument> InnerMatcher +Matcher<TemplateSpecializationType>hasTemplateArgumentunsigned N, Matcher<TemplateArgument> InnerMatcher
Matches classTemplateSpecializations where the n'th TemplateArgument
 matches the given InnerMatcher.
 
@@ -4660,7 +5360,7 @@ 

AST Traversal Matchers

-Matcher<TemplateTypeParmType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<TemplateTypeParmType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4673,12 +5373,12 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
@@ -4698,7 +5398,20 @@

AST Traversal Matchers

-Matcher<TypedefType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<TypedefNameDecl>hasTypeMatcher<QualType> InnerMatcher +
Matches if the expression's or declaration's type matches a type
+matcher.
+
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and U (matcher = typedefDecl(hasType(asString("int")))
+ class X {};
+ void y(X &x) { x; X z; }
+ typedef int U;
+
+ + +Matcher<TypedefType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4711,16 +5424,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<UnaryExprOrTypeTraitExpr>hasArgumentOfTypeMatcher<QualType> InnerMatcher +Matcher<UnaryExprOrTypeTraitExpr>hasArgumentOfTypeMatcher<QualType> InnerMatcher
Matches unary expressions that have a specific type of argument.
 
 Given
@@ -4730,7 +5443,7 @@ 

AST Traversal Matchers

-Matcher<UnaryOperator>hasUnaryOperandMatcher<Expr> InnerMatcher +Matcher<UnaryOperator>hasUnaryOperandMatcher<Expr> InnerMatcher
Matches if the operand of a unary operator matches.
 
 Example matches true (matcher = hasUnaryOperand(
@@ -4739,7 +5452,7 @@ 

AST Traversal Matchers

-Matcher<UnresolvedUsingType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<UnresolvedUsingType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
 
@@ -4752,16 +5465,16 @@ 

AST Traversal Matchers

Also usable as Matcher<T> for any T supporting the getDecl() member function. e.g. various subtypes of clang::Type and various expressions. -Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, - Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, - Matcher<RecordType>, Matcher<TagType>, - Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, - Matcher<TypedefType>, Matcher<UnresolvedUsingType> +Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, + Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, + Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, + Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, + Matcher<TypedefType>, Matcher<UnresolvedUsingType>
-Matcher<UsingDecl>hasAnyUsingShadowDeclMatcher<UsingShadowDecl> InnerMatcher +Matcher<UsingDecl>hasAnyUsingShadowDeclMatcher<UsingShadowDecl> InnerMatcher
Matches any using shadow declaration.
 
 Given
@@ -4771,7 +5484,7 @@ 

AST Traversal Matchers

matches using X::b
-Matcher<UsingShadowDecl>hasTargetDeclMatcher<NamedDecl> InnerMatcher +Matcher<UsingShadowDecl>hasTargetDeclMatcher<NamedDecl> InnerMatcher
Matches a using shadow declaration where the target declaration is
 matched by the given matcher.
 
@@ -4783,8 +5496,8 @@ 

AST Traversal Matchers

matches using X::b but not using X::a
-Matcher<ValueDecl>hasTypeMatcher<Decl> InnerMatcher -
Overloaded to match the declaration of the expression's or value
+Matcher<ValueDecl>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),
@@ -4798,22 +5511,24 @@ 

AST Traversal Matchers

class X {}; void y(X &x) { x; X z; } -Usable as: Matcher<Expr>, Matcher<ValueDecl> +Usable as: Matcher<Expr>, Matcher<ValueDecl>
-Matcher<ValueDecl>hasTypeMatcher<QualType> InnerMatcher -
Matches if the expression's or declaration's type matches a type
+Matcher<ValueDecl>hasTypeMatcher<QualType> InnerMatcher
+
Matches if the expression's or declaration's type matches a type
 matcher.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and U (matcher = typedefDecl(hasType(asString("int")))
  class X {};
  void y(X &x) { x; X z; }
+ typedef int U;
 
-Matcher<VarDecl>hasInitializerMatcher<Expr> InnerMatcher +Matcher<VarDecl>hasInitializerMatcher<Expr> InnerMatcher
Matches a variable declaration that has an initializer expression
 that matches the given matcher.
 
@@ -4823,7 +5538,7 @@ 

AST Traversal Matchers

-Matcher<VariableArrayType>hasSizeExprMatcher<Expr> InnerMatcher +Matcher<VariableArrayType>hasSizeExprMatcher<Expr> InnerMatcher
Matches VariableArrayType nodes that have a specific size
 expression.
 
@@ -4837,9 +5552,9 @@ 

AST Traversal Matchers

-Matcher<WhileStmt>hasBodyMatcher<Stmt> InnerMatcher -
Matches a 'for', 'while', or 'do while' statement that has
-a given body.
+Matcher<WhileStmt>hasBodyMatcher<Stmt> InnerMatcher
+
Matches a 'for', 'while', 'do while' statement or a function
+definition that has a given body.
 
 Given
   for (;;) {}
@@ -4850,22 +5565,22 @@ 

AST Traversal Matchers

-Matcher<WhileStmt>hasConditionMatcher<Expr> InnerMatcher +Matcher<WhileStmt>hasConditionMatcher<Expr> InnerMatcher
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
-Matcher<internal::BindableMatcher<NestedNameSpecifierLoc>>locMatcher<NestedNameSpecifier> InnerMatcher +Matcher<internal::BindableMatcher<NestedNameSpecifierLoc>>locMatcher<NestedNameSpecifier> InnerMatcher
Matches NestedNameSpecifierLocs for which the given inner
 NestedNameSpecifier-matcher matches.
 
-Matcher<internal::BindableMatcher<TypeLoc>>locMatcher<QualType> InnerMatcher +Matcher<internal::BindableMatcher<TypeLoc>>locMatcher<QualType> InnerMatcher
Matches TypeLocs for which the given inner
 QualType-matcher matches.
 
diff --git a/docs/MSVCCompatibility.rst b/docs/MSVCCompatibility.rst index 3794813db81..ead0ae847a2 100644 --- a/docs/MSVCCompatibility.rst +++ b/docs/MSVCCompatibility.rst @@ -84,18 +84,23 @@ The status of major ABI-impacting C++ features: * RTTI: :good:`Complete`. Generation of RTTI data structures has been finished, along with support for the ``/GR`` flag. -* Exceptions and SEH: :partial:`Partial`. - C++ exceptions (``try`` / ``catch`` / ``throw``) and - structured exceptions (``__try`` / ``__except`` / ``__finally``) mostly - work on x64. 32-bit exception handling support is being worked on. LLVM does - not model asynchronous exceptions, so it is currently impossible to catch an - asynchronous exception generated in the same frame as the catching ``__try``. +* C++ Exceptions: :good:`Mostly complete`. Support for + C++ exceptions (``try`` / ``catch`` / ``throw``) have been implemented for + x86 and x64. Our implementation has been well tested but we still get the + odd bug report now and again. C++ exception specifications are ignored, but this is `consistent with Visual C++`_. .. _consistent with Visual C++: https://msdn.microsoft.com/en-us/library/wfa0edys.aspx +* Asynchronous Exceptions (SEH): :partial:`Partial`. + Structured exceptions (``__try`` / ``__except`` / ``__finally``) mostly + work on x86 and x64. + LLVM does not model asynchronous exceptions, so it is currently impossible to + catch an asynchronous exception generated in the same frame as the catching + ``__try``. + * Thread-safe initialization of local statics: :good:`Complete`. MSVC 2015 added support for thread-safe initialization of such variables by taking an ABI break. diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index a6c6e6c43be..00000000000 --- a/docs/Makefile +++ /dev/null @@ -1,110 +0,0 @@ -##===- docs/Makefile ---------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := .. - -ifdef BUILD_FOR_WEBSITE -PROJ_OBJ_DIR = . -DOXYGEN = doxygen - -$(PROJ_OBJ_DIR)/doxygen.cfg: doxygen.cfg.in - cat $< | sed \ - -e 's/@DOT@/dot/g' \ - -e 's/@PACKAGE_VERSION@/mainline/' \ - -e 's/@abs_builddir@/./g' \ - -e 's/@abs_srcdir@/./g' \ - -e 's/@clang_doxygen_generate_qhp@/NO/g' \ - -e 's/@clang_doxygen_qch_filename@//g' \ - -e 's/@clang_doxygen_qhelpgenerator_path@//g' \ - -e 's/@clang_doxygen_qhp_cust_filter_attrs@//g' \ - -e 's/@clang_doxygen_qhp_cust_filter_name@//g' \ - -e 's/@clang_doxygen_qhp_namespace@//g' \ - -e 's/@enable_external_search@/NO/g' \ - -e 's/@enable_searchengine@/NO/g' \ - -e 's/@enable_server_based_search@/NO/g' \ - -e 's/@extra_search_mappings@//g' \ - -e 's/@searchengine_url@//g' \ - -e 's/@DOT_IMAGE_FORMAT@/png/g' \ - > $@ -endif - -include $(CLANG_LEVEL)/Makefile - -HTML := $(wildcard $(PROJ_SRC_DIR)/*.html) \ - $(wildcard $(PROJ_SRC_DIR)/*.css) -#IMAGES := $(wildcard $(PROJ_SRC_DIR)/img/*.*) -DOXYFILES := doxygen.cfg.in doxygen.intro - -.PHONY: install-html install-doxygen doxygen generated - -install_targets := -ifndef ONLY_MAN_DOCS -install_targets += install-html -endif -ifeq ($(ENABLE_DOXYGEN),1) -install_targets += install-doxygen -endif -install-local:: $(install_targets) - -# Live documentation is generated for the web site using this target: -# 'make generated BUILD_FOR_WEBSITE=1' -generated:: doxygen - -install-html: $(PROJ_OBJ_DIR)/html.tar.gz - $(Echo) Installing HTML documentation - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/img - $(Verb) $(DataInstall) $(HTML) $(DESTDIR)$(PROJ_docsdir)/html -# $(Verb) $(DataInstall) $(IMAGES) $(DESTDIR)$(PROJ_docsdir)/html/img - $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(DESTDIR)$(PROJ_docsdir) - -$(PROJ_OBJ_DIR)/html.tar.gz: $(HTML) - $(Echo) Packaging HTML documentation - $(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/html.tar - $(Verb) cd $(PROJ_SRC_DIR) && \ - $(TAR) cf $(PROJ_OBJ_DIR)/html.tar *.html - $(Verb) $(GZIPBIN) $(PROJ_OBJ_DIR)/html.tar - -install-doxygen: doxygen - $(Echo) Installing doxygen documentation - $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(DESTDIR)$(PROJ_docsdir) - $(Verb) cd $(PROJ_OBJ_DIR)/doxygen/html && \ - for DIR in $$($(FIND) . -type d); do \ - DESTSUB="$(DESTDIR)$(PROJ_docsdir)/html/doxygen/$$(echo $$DIR | cut -c 3-)"; \ - $(MKDIR) $$DESTSUB && \ - $(FIND) $$DIR -maxdepth 1 -type f -exec $(DataInstall) {} $$DESTSUB \; ; \ - if [ $$? != 0 ]; then exit 1; fi \ - done - -doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz - -regendoc: - $(Echo) Building doxygen documentation - $(Verb) $(RM) -rf $(PROJ_OBJ_DIR)/doxygen - $(Verb) $(DOXYGEN) $(PROJ_OBJ_DIR)/doxygen.cfg - $(Verb) sed -i "s/[$$]LatestRev[$$]/`svnversion $(PROJ_SRC_DIR)`/g" \ - $(PROJ_OBJ_DIR)/doxygen/html/*.html - -$(PROJ_OBJ_DIR)/doxygen.tar.gz: $(DOXYFILES) $(PROJ_OBJ_DIR)/doxygen.cfg - $(Echo) Packaging doxygen documentation - $(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/doxygen.tar - $(Verb) $(TAR) cf $(PROJ_OBJ_DIR)/doxygen.tar doxygen - $(Verb) $(GZIPBIN) $(PROJ_OBJ_DIR)/doxygen.tar - $(Verb) $(CP) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_OBJ_DIR)/doxygen/html/ - -userloc: $(LLVM_SRC_ROOT)/docs/userloc.html - -$(LLVM_SRC_ROOT)/docs/userloc.html: - $(Echo) Making User LOC Table - $(Verb) cd $(LLVM_SRC_ROOT) ; ./utils/userloc.pl -details -recurse \ - -html lib include tools runtime utils examples autoconf test > docs/userloc.html - -uninstall-local:: - $(Echo) Uninstalling Documentation - $(Verb) $(RM) -rf $(DESTDIR)$(PROJ_docsdir) diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst index 62cacce215d..4e58588b801 100644 --- a/docs/MemorySanitizer.rst +++ b/docs/MemorySanitizer.rst @@ -171,6 +171,8 @@ Handling external code MemorySanitizer requires that all program code is instrumented. This also includes any libraries that the program depends on, even libc. Failing to achieve this may result in false reports. +For the same reason you may need to replace all inline assembly code that writes to memory +with a pure C/C++ code. Full MemorySanitizer instrumentation is very difficult to achieve. To make it easier, MemorySanitizer runtime library includes 70+ diff --git a/docs/PCHInternals.rst b/docs/PCHInternals.rst index 8f66ddf0e1d..b0372cb931a 100644 --- a/docs/PCHInternals.rst +++ b/docs/PCHInternals.rst @@ -15,7 +15,7 @@ Using Precompiled Headers with ``clang`` The Clang compiler frontend, ``clang -cc1``, supports two command line options for generating and using PCH files. -To generate PCH files using ``clang -cc1``, use the option :option:`-emit-pch`: +To generate PCH files using ``clang -cc1``, use the option `-emit-pch`: .. code-block:: bash @@ -24,7 +24,7 @@ To generate PCH files using ``clang -cc1``, use the option :option:`-emit-pch`: This option is transparently used by ``clang`` when generating PCH files. The resulting PCH file contains the serialized form of the compiler's internal representation after it has completed parsing and semantic analysis. The PCH -file can then be used as a prefix header with the :option:`-include-pch` +file can then be used as a prefix header with the `-include-pch` option: .. code-block:: bash @@ -84,7 +84,7 @@ With this approach, the cost of using an AST file for a translation unit is proportional to the amount of code actually used from the AST file, rather than being proportional to the size of the AST file itself. -When given the :option:`-print-stats` option, Clang produces statistics +When given the `-print-stats` option, Clang produces statistics describing how much of the AST file was actually loaded from disk. For a simple "Hello, World!" program that includes the Apple ``Cocoa.h`` header (which is built as a precompiled header), this option illustrates how little of diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 5a25e0b0632..cdbf7e696be 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -11,8 +11,8 @@ Written by the `LLVM Team `_ .. warning:: These are in-progress notes for the upcoming Clang 3.9 release. You may - prefer the `Clang 3.7 Release Notes - `_. + prefer the `Clang 3.8 Release Notes + `_. Introduction ============ @@ -47,14 +47,20 @@ sections with improvements to Clang's support for those languages. Major New Features ------------------ -- Feature1... +- Clang will no longer passes --build-id by default to the linker. In modern + linkers that is a relatively expensive option. It can be passed explicitly + with -Wl,--build-id. To have clang always pass it, build clang with + -DENABLE_LINKER_BUILD_ID. +- On Itanium ABI targets, attribute abi_tag is now supported for compatibility + with GCC. Clang implementation of abi_tag is mostly compatible with GCC ABI + version 10. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Clang's diagnostics are constantly being improved to catch more issues, explain them more clearly, and provide more accurate source information -about them. The improvements since the 3.7 release include: +about them. The improvements since the 3.8 release include: - ... @@ -69,14 +75,35 @@ New Pragmas in Clang Clang now supports the ... + +Attribute Changes in Clang +-------------------------- + +- The ``nodebug`` attribute may now be applied to static, global, and local + variables (but not parameters or non-static data members). This will suppress + all debugging information for the variable (and its type, if there are no + other uses of the type). + + Windows Support --------------- Clang's support for building native Windows programs ... +TLS is enabled for Cygwin defaults to -femulated-tls. + +Proper support, including correct mangling and overloading, added for +MS-specific "__unaligned" type qualifier. + C Language Changes in Clang --------------------------- +The -faltivec and -maltivec flags no longer silently include altivec.h on Power platforms. + +`RenderScript +`_ +support added to the Frontend and enabled by the '-x renderscript' option or +the '.rs' file extension. ... @@ -88,11 +115,61 @@ C11 Feature Support C++ Language Changes in Clang ----------------------------- -- ... +- Clang now enforces the rule that a *using-declaration* cannot name an enumerator of a + scoped enumeration. + + .. code-block:: c++ + + namespace Foo { enum class E { e }; } + namespace Bar { + using Foo::E::e; // error + constexpr auto e = Foo::E::e; // ok + } + +- Clang now enforces the rule that an enumerator of an unscoped enumeration declared at + class scope can only be named by a *using-declaration* in a derived class. + + .. code-block:: c++ + + class Foo { enum E { e }; } + using Foo::e; // error + static constexpr auto e = Foo::e; // ok + +... -C++11 Feature Support +C++1z Feature Support ^^^^^^^^^^^^^^^^^^^^^ +Clang's experimental support for the upcoming C++1z standard can be enabled with ``-std=c++1z``. +Changes to C++1z features since Clang 3.8: + +- The ``[[fallthrough]]``, ``[[nodiscard]]``, and ``[[maybe_unused]]`` attributes are + supported in C++11 onwards, and are largely synonymous with Clang's existing attributes + ``[[clang::fallthrough]]``, ``[[gnu::warn_unused_result]]``, and ``[[gnu::unused]]``. + Use ``-Wimplicit-fallthrough`` to warn on unannotated fallthrough within ``switch`` + statements. + +- In C++1z mode, aggregate initialization can be performed for classes with base classes: + + .. code-block:: c++ + + struct A { int n; }; + struct B : A { int x, y; }; + B b = { 1, 2, 3 }; // b.n == 1, b.x == 2, b.y == 3 + +- The range in a range-based ``for`` statement can have different types for its ``begin`` + and ``end`` iterators. This is permitted as an extension in C++11 onwards. + +- Lambda-expressions can explicitly capture ``*this`` (to capture the surrounding object + by copy). This is permitted as an extension in C++11 onwards. + +- Objects of enumeration type can be direct-list-initialized from a value of the underlying + type. ``E{n}`` is equivalent to ``E(n)``, except that it implies a check for a narrowing + conversion. + +- Unary *fold-expression*\s over an empty pack are now rejected for all operators + other than ``&&``, ``||``, and ``,``. + ... Objective-C Language Changes in Clang @@ -105,6 +182,21 @@ OpenCL C Language Changes in Clang ... +OpenMP Support in Clang +---------------------------------- + +Added support for all non-offloading features from OpenMP 4.5, including using +data members in private clauses of non-static member functions. Additionally, +data members can be used as loop control variables in loop-based directives. + +Currently Clang supports OpenMP 3.1 and all non-offloading features of +OpenMP 4.0/4.5. Offloading features are under development. Clang defines macro +_OPENMP and sets it to OpenMP 3.1 (in accordance with OpenMP standard) by +default. User may change this value using ``-fopenmp-version=[31|40|45]`` option. + +The codegen for OpenMP constructs was significantly improved to produce much +more stable and faster code. + Internal API Changes -------------------- @@ -117,6 +209,14 @@ this section should help get you past the largest hurdles of upgrading. AST Matchers ------------ +- has and hasAnyArgument: Matchers no longer ignores parentheses and implicit + casts on the argument before applying the inner matcher. The fix was done to + allow for greater control by the user. In all existing checkers that use this + matcher all instances of code ``hasAnyArgument()`` or + ``has()`` must be changed to + ``hasAnyArgument(ignoringParenImpCasts())`` or + ``has(ignoringParenImpCasts())``. + ... libclang diff --git a/docs/SafeStack.rst b/docs/SafeStack.rst index 21e9b6c621a..f01b75f5cb3 100644 --- a/docs/SafeStack.rst +++ b/docs/SafeStack.rst @@ -178,6 +178,17 @@ Please refer to the `Code-Pointer Integrity `__ project page for more information about the design of the SafeStack and its related technologies. +setjmp and exception handling +----------------------------- + +The `OSDI'14 paper `_ mentions that +on Linux the instrumentation pass finds calls to setjmp or functions that +may throw an exception, and inserts required instrumentation at their call +sites. Specifically, the instrumentation pass saves the shadow stack pointer +on the safe stack before the call site, and restores it either after the +call to setjmp or after an exception has been caught. This is implemented +in the function ``SafeStack::createStackRestorePoints``. + Publications ------------ diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst index e759b351c1b..f7ec65fdd15 100644 --- a/docs/SanitizerCoverage.rst +++ b/docs/SanitizerCoverage.rst @@ -16,8 +16,9 @@ How to build and run ==================== SanitizerCoverage can be used with :doc:`AddressSanitizer`, -:doc:`LeakSanitizer`, :doc:`MemorySanitizer`, and UndefinedBehaviorSanitizer. -In addition to ``-fsanitize=``, pass one of the following compile-time flags: +:doc:`LeakSanitizer`, :doc:`MemorySanitizer`, +UndefinedBehaviorSanitizer, or without any sanitizer. Pass one of the +following compile-time flags: * ``-fsanitize-coverage=func`` for function-level coverage (very fast). * ``-fsanitize-coverage=bb`` for basic-block-level coverage (may add up to 30% @@ -27,8 +28,9 @@ In addition to ``-fsanitize=``, pass one of the following compile-time flags: You may also specify ``-fsanitize-coverage=indirect-calls`` for additional `caller-callee coverage`_. -At run time, pass ``coverage=1`` in ``ASAN_OPTIONS``, ``LSAN_OPTIONS``, -``MSAN_OPTIONS`` or ``UBSAN_OPTIONS``, as appropriate. +At run time, pass ``coverage=1`` in ``ASAN_OPTIONS``, +``LSAN_OPTIONS``, ``MSAN_OPTIONS`` or ``UBSAN_OPTIONS``, as +appropriate. For the standalone coverage mode, use ``UBSAN_OPTIONS``. To get `Coverage counters`_, add ``-fsanitize-coverage=8bit-counters`` to one of the above compile-time flags. At runtime, use @@ -94,6 +96,41 @@ numbers: cov.cc:3 cov.cc:5 +Sancov Tool +=========== + +A new experimental ``sancov`` tool is developed to process coverage files. +The tool is part of LLVM project and is currently supported only on Linux. +It can handle symbolization tasks autonomously without any extra support +from the environment. You need to pass .sancov files (named +``..sancov`` and paths to all corresponding binary elf files. +Sancov matches these files using module names and binaries file names. + +.. code-block:: console + + USAGE: sancov [options] (|<.sancov file>)... + + Action (required) + -print - Print coverage addresses + -covered-functions - Print all covered functions. + -not-covered-functions - Print all not covered functions. + -html-report - Print HTML coverage report. + + Options + -blacklist= - Blacklist file (sanitizer blacklist format). + -demangle - Print demangled function name. + -strip_path_prefix= - Strip this prefix from file paths in reports + + +Automatic HTML Report Generation +================================ + +If ``*SAN_OPTIONS`` contains ``html_cov_report=1`` option set, then html +coverage report would be automatically generated alongside the coverage files. +The ``sancov`` binary should be present in ``PATH`` or +``sancov_path=`_'s coverage +`AFL `__'s coverage instrumentation. With additional compile-time and run-time flags you can get more sensitive coverage information. In addition to boolean values assigned to every basic block (edge) the instrumentation will collect imprecise counters. @@ -251,10 +288,38 @@ These counters may also be used for in-process coverage-guided fuzzers. See Tracing basic blocks ==================== -An *experimental* feature to support basic block (or edge) tracing. +Experimental support for basic block (or edge) tracing. With ``-fsanitize-coverage=trace-bb`` the compiler will insert ``__sanitizer_cov_trace_basic_block(s32 *id)`` before every function, basic block, or edge (depending on the value of ``-fsanitize-coverage=[func,bb,edge]``). +Example: + +.. code-block:: console + + % clang -g -fsanitize=address -fsanitize-coverage=edge,trace-bb foo.cc + % ASAN_OPTIONS=coverage=1 ./a.out + +This will produce two files after the process exit: +`trace-points.PID.sancov` and `trace-events.PID.sancov`. +The first file will contain a textual description of all the instrumented points in the program +in the form that you can feed into llvm-symbolizer (e.g. `a.out 0x4dca89`), one per line. +The second file will contain the actual execution trace as a sequence of 4-byte integers +-- these integers are the indices into the array of instrumented points (the first file). + +Basic block tracing is currently supported only for single-threaded applications. + + +Tracing PCs +=========== +*Experimental* feature similar to tracing basic blocks, but with a different API. +With ``-fsanitize-coverage=trace-pc`` the compiler will insert +``__sanitizer_cov_trace_pc()`` on every edge. +With an additional ``...=trace-pc,indirect-calls`` flag +``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call. +These callbacks are not implemented in the Sanitizer run-time and should be defined +by the user. So, these flags do not require the other sanitizer to be used. +This mechanism is used for fuzzing the Linux kernel (https://github.com/google/syzkaller) +and can be used with `AFL `__. Tracing data flow ================= diff --git a/docs/SanitizerStats.rst b/docs/SanitizerStats.rst new file mode 100644 index 00000000000..cff68f6b5d5 --- /dev/null +++ b/docs/SanitizerStats.rst @@ -0,0 +1,62 @@ +============== +SanitizerStats +============== + +.. contents:: + :local: + +Introduction +============ + +The sanitizers support a simple mechanism for gathering profiling statistics +to help understand the overhead associated with sanitizers. + +How to build and run +==================== + +SanitizerStats can currently only be used with :doc:`ControlFlowIntegrity`. +In addition to ``-fsanitize=cfi*``, pass the ``-fsanitize-stats`` flag. +This will cause the program to count the number of times that each control +flow integrity check in the program fires. + +At run time, set the ``SANITIZER_STATS_PATH`` environment variable to direct +statistics output to a file. The file will be written on process exit. +The following substitutions will be applied to the environment variable: + + - ``%b`` -- The executable basename. + - ``%p`` -- The process ID. + +You can also send the ``SIGUSR2`` signal to a process to make it write +sanitizer statistics immediately. + +The ``sanstats`` program can be used to dump statistics. It takes as a +command line argument the path to a statistics file produced by a program +compiled with ``-fsanitize-stats``. + +The output of ``sanstats`` is in four columns, separated by spaces. The first +column is the file and line number of the call site. The second column is +the function name. The third column is the type of statistic gathered (in +this case, the type of control flow integrity check). The fourth column is +the call count. + +Example: + +.. code-block:: console + + $ cat -n vcall.cc + 1 struct A { + 2 virtual void f() {} + 3 }; + 4 + 5 __attribute__((noinline)) void g(A *a) { + 6 a->f(); + 7 } + 8 + 9 int main() { + 10 A a; + 11 g(&a); + 12 } + $ clang++ -fsanitize=cfi -flto -fuse-ld=gold vcall.cc -fsanitize-stats -g + $ SANITIZER_STATS_PATH=a.stats ./a.out + $ sanstats a.stats + vcall.cc:6 _Z1gP1A cfi-vcall 1 diff --git a/docs/SourceBasedCodeCoverage.rst b/docs/SourceBasedCodeCoverage.rst new file mode 100644 index 00000000000..8d0a51fd331 --- /dev/null +++ b/docs/SourceBasedCodeCoverage.rst @@ -0,0 +1,237 @@ +========================== +Source-based Code Coverage +========================== + +.. contents:: + :local: + +Introduction +============ + +This document explains how to use clang's source-based code coverage feature. +It's called "source-based" because it operates on AST and preprocessor +information directly. This allows it to generate very precise coverage data. + +Clang ships two other code coverage implementations: + +* :doc:`SanitizerCoverage` - A low-overhead tool meant for use alongside the + various sanitizers. It can provide up to edge-level coverage. + +* gcov - A GCC-compatible coverage implementation which operates on DebugInfo. + +From this point onwards "code coverage" will refer to the source-based kind. + +The code coverage workflow +========================== + +The code coverage workflow consists of three main steps: + +* Compiling with coverage enabled. + +* Running the instrumented program. + +* Creating coverage reports. + +The next few sections work through a complete, copy-'n-paste friendly example +based on this program: + +.. code-block:: cpp + + % cat < foo.cc + #define BAR(x) ((x) || (x)) + template void foo(T x) { + for (unsigned I = 0; I < 10; ++I) { BAR(I); } + } + int main() { + foo(0); + foo(0); + return 0; + } + EOF + +Compiling with coverage enabled +=============================== + +To compile code with coverage enabled, pass ``-fprofile-instr-generate +-fcoverage-mapping`` to the compiler: + +.. code-block:: console + + # Step 1: Compile with coverage enabled. + % clang++ -fprofile-instr-generate -fcoverage-mapping foo.cc -o foo + +Note that linking together code with and without coverage instrumentation is +supported: any uninstrumented code simply won't be accounted for. + +Running the instrumented program +================================ + +The next step is to run the instrumented program. When the program exits it +will write a **raw profile** to the path specified by the ``LLVM_PROFILE_FILE`` +environment variable. If that variable does not exist, the profile is written +to ``default.profraw`` in the current directory of the program. If +``LLVM_PROFILE_FILE`` contains a path to a non-existent directory, the missing +directory structure will be created. Additionally, the following special +**pattern strings** are rewritten: + +* "%p" expands out to the process ID. + +* "%h" expands out to the hostname of the machine running the program. + +* "%Nm" expands out to the instrumented binary's signature. When this pattern + is specified, the runtime creates a pool of N raw profiles which are used for + on-line profile merging. The runtime takes care of selecting a raw profile + from the pool, locking it, and updating it before the program exits. If N is + not specified (i.e the pattern is "%m"), it's assumed that ``N = 1``. N must + be between 1 and 9. The merge pool specifier can only occur once per filename + pattern. + +.. code-block:: console + + # Step 2: Run the program. + % LLVM_PROFILE_FILE="foo.profraw" ./foo + +Creating coverage reports +========================= + +Raw profiles have to be **indexed** before they can be used to generate +coverage reports. This is done using the "merge" tool in ``llvm-profdata``, so +named because it can combine and index profiles at the same time: + +.. code-block:: console + + # Step 3(a): Index the raw profile. + % llvm-profdata merge -sparse foo.profraw -o foo.profdata + +There are multiple different ways to render coverage reports. One option is to +generate a line-oriented report: + +.. code-block:: console + + # Step 3(b): Create a line-oriented coverage report. + % llvm-cov show ./foo -instr-profile=foo.profdata + +To demangle any C++ identifiers in the output, use: + +.. code-block:: console + + % llvm-cov show ./foo -instr-profile=foo.profdata | c++filt -n + +This report includes a summary view as well as dedicated sub-views for +templated functions and their instantiations. For our example program, we get +distinct views for ``foo(...)`` and ``foo(...)``. If +``-show-line-counts-or-regions`` is enabled, ``llvm-cov`` displays sub-line +region counts (even in macro expansions): + +.. code-block:: none + + 20| 1|#define BAR(x) ((x) || (x)) + ^20 ^2 + 2| 2|template void foo(T x) { + 22| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); } + ^22 ^20 ^20^20 + 2| 4|} + ------------------ + | void foo(int): + | 1| 2|template void foo(T x) { + | 11| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); } + | ^11 ^10 ^10^10 + | 1| 4|} + ------------------ + | void foo(int): + | 1| 2|template void foo(T x) { + | 11| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); } + | ^11 ^10 ^10^10 + | 1| 4|} + ------------------ + +It's possible to generate a file-level summary of coverage statistics (instead +of a line-oriented report) with: + +.. code-block:: console + + # Step 3(c): Create a coverage summary. + % llvm-cov report ./foo -instr-profile=foo.profdata + Filename Regions Miss Cover Functions Executed + ----------------------------------------------------------------------- + /tmp/foo.cc 13 0 100.00% 3 100.00% + ----------------------------------------------------------------------- + TOTAL 13 0 100.00% 3 100.00% + +A few final notes: + +* The ``-sparse`` flag is optional but can result in dramatically smaller + indexed profiles. This option should not be used if the indexed profile will + be reused for PGO. + +* Raw profiles can be discarded after they are indexed. Advanced use of the + profile runtime library allows an instrumented program to merge profiling + information directly into an existing raw profile on disk. The details are + out of scope. + +* The ``llvm-profdata`` tool can be used to merge together multiple raw or + indexed profiles. To combine profiling data from multiple runs of a program, + try e.g: + + .. code-block:: console + + % llvm-profdata merge -sparse foo1.profraw foo2.profdata -o foo3.profdata + +Format compatibility guarantees +=============================== + +* There are no backwards or forwards compatibility guarantees for the raw + profile format. Raw profiles may be dependent on the specific compiler + revision used to generate them. It's inadvisable to store raw profiles for + long periods of time. + +* Tools must retain **backwards** compatibility with indexed profile formats. + These formats are not forwards-compatible: i.e, a tool which uses format + version X will not be able to understand format version (X+k). + +* There is a third format in play: the format of the coverage mappings emitted + into instrumented binaries. Tools must retain **backwards** compatibility + with these formats. These formats are not forwards-compatible. + +Using the profiling runtime without static initializers +======================================================= + +By default the compiler runtime uses a static initializer to determine the +profile output path and to register a writer function. To collect profiles +without using static initializers, do this manually: + +* Export a ``int __llvm_profile_runtime`` symbol from each instrumented shared + library and executable. When the linker finds a definition of this symbol, it + knows to skip loading the object which contains the profiling runtime's + static initializer. + +* Forward-declare ``void __llvm_profile_initialize_file(void)`` and call it + once from each instrumented executable. This function parses + ``LLVM_PROFILE_FILE``, sets the output path, and truncates any existing files + at that path. To get the same behavior without truncating existing files, + pass a filename pattern string to ``void __llvm_profile_set_filename(char + *)``. These calls can be placed anywhere so long as they precede all calls + to ``__llvm_profile_write_file``. + +* Forward-declare ``int __llvm_profile_write_file(void)`` and call it to write + out a profile. This function returns 0 when it succeeds, and a non-zero value + otherwise. Calling this function multiple times appends profile data to an + existing on-disk raw profile. + +Drawbacks and limitations +========================= + +* Code coverage does not handle unpredictable changes in control flow or stack + unwinding in the presence of exceptions precisely. Consider the following + function: + + .. code-block:: cpp + + int f() { + may_throw(); + return 0; + } + + If the call to ``may_throw()`` propagates an exception into ``f``, the code + coverage tool may mark the ``return`` statement as executed even though it is + not. A call to ``longjmp()`` can have similar effects. diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst index 0b9b163a965..cfb0a952e12 100644 --- a/docs/ThreadSanitizer.rst +++ b/docs/ThreadSanitizer.rst @@ -30,7 +30,7 @@ and line numbers in the warning messages. Example: -.. code-block:: c++ +.. code-block:: console % cat projects/compiler-rt/lib/tsan/lit_tests/tiny_race.c #include diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst index 37ff16d9a9e..7babb96a65a 100644 --- a/docs/UndefinedBehaviorSanitizer.rst +++ b/docs/UndefinedBehaviorSanitizer.rst @@ -92,11 +92,14 @@ Available checks are: parameter which is declared to never be null. - ``-fsanitize=null``: Use of a null pointer or creation of a null reference. - - ``-fsanitize=object-size``: An attempt to use bytes which the - optimizer can determine are not part of the object being - accessed. The sizes of objects are determined using - ``__builtin_object_size``, and consequently may be able to detect - more problems at higher optimization levels. + - ``-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 + directly access memory, but are provably incorrect given the size of + the objects involved, such as invalid downcasts and calling methods on + invalid pointers. These checks are made in terms of + ``__builtin_object_size``, and consequently may be able to detect more + problems at higher optimization levels. - ``-fsanitize=return``: In C++, reaching the end of a value-returning function without returning a value. - ``-fsanitize=returns-nonnull-attribute``: Returning null pointer @@ -168,6 +171,38 @@ UndefinedBehaviorSanitizer supports ``src`` and ``fun`` entity types in :doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports in the specified source files or functions. +Runtime suppressions +-------------------- + +Sometimes you can suppress UBSan error reports for specific files, functions, +or libraries without recompiling the code. You need to pass a path to +suppression file in a ``UBSAN_OPTIONS`` environment variable. + +.. code-block:: bash + + UBSAN_OPTIONS=suppressions=MyUBSan.supp + +You need to specify a :ref:`check ` you are suppressing and the +bug location. For example: + +.. code-block:: bash + + signed-integer-overflow:file-with-known-overflow.cpp + alignment:function_doing_unaligned_access + vptr:shared_object_with_vptr_failures.so + +There are several limitations: + +* Sometimes your binary must have enough debug info and/or symbol table, so + that the runtime could figure out source file or function name to match + against the suppression. +* It is only possible to suppress recoverable checks. For the example above, + you can additionally pass + ``-fsanitize-recover=signed-integer-overflow,alignment,vptr``, although + most of UBSan checks are recoverable by default. +* Check groups (like ``undefined``) can't be used in suppressions file, only + fine-grained checks are supported. + Supported Platforms =================== @@ -193,6 +228,26 @@ UndefinedBehaviorSanitizer is available on selected platforms starting from LLVM 3.3. The test suite is integrated into the CMake build and can be run with ``check-ubsan`` command. +Additional Configuration +======================== + +UndefinedBehaviorSanitizer adds static check data for each check unless it is +in trap mode. This check data includes the full file name. The option +``-fsanitize-undefined-strip-path-components=N`` can be used to trim this +information. If ``N`` is positive, file information emitted by +UndefinedBehaviorSanitizer will drop the first ``N`` components from the file +path. If ``N`` is negative, the last ``N`` components will be kept. + +Example +------- + +For a file called ``/code/library/file.cpp``, here is what would be emitted: +* Default (No flag, or ``-fsanitize-undefined-strip-path-components=0``): ``/code/library/file.cpp`` +* ``-fsanitize-undefined-strip-path-components=1``: ``code/library/file.cpp`` +* ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp`` +* ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp`` +* ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp`` + More Information ================ diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index 5fe1e371df6..2ebcbdf6031 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -133,13 +133,13 @@ Options to Control Error and Warning Messages .. option:: -ferror-limit=123 Stop emitting diagnostics after 123 errors have been produced. The default is - 20, and the error limit can be disabled with :option:`-ferror-limit=0`. + 20, and the error limit can be disabled with `-ferror-limit=0`. .. option:: -ftemplate-backtrace-limit=123 Only emit up to 123 template instantiation notes within the template instantiation backtrace for a single warning or error. The default is 10, and - the limit can be disabled with :option:`-ftemplate-backtrace-limit=0`. + the limit can be disabled with `-ftemplate-backtrace-limit=0`. .. _cl_diag_formatting: @@ -543,15 +543,15 @@ vectorize a loop body. Clang offers a family of flags which the optimizers can use to emit a diagnostic in three cases: -1. When the pass makes a transformation (:option:`-Rpass`). +1. When the pass makes a transformation (`-Rpass`). -2. When the pass fails to make a transformation (:option:`-Rpass-missed`). +2. When the pass fails to make a transformation (`-Rpass-missed`). 3. When the pass determines whether or not to make a transformation - (:option:`-Rpass-analysis`). + (`-Rpass-analysis`). -NOTE: Although the discussion below focuses on :option:`-Rpass`, the exact -same options apply to :option:`-Rpass-missed` and :option:`-Rpass-analysis`. +NOTE: Although the discussion below focuses on `-Rpass`, the exact +same options apply to `-Rpass-missed` and `-Rpass-analysis`. Since there are dozens of passes inside the compiler, each of these flags take a regular expression that identifies the name of the pass which should @@ -567,7 +567,7 @@ compile the code with: Note that remarks from the inliner are identified with `[-Rpass=inline]`. To request a report from every optimization pass, you should use -:option:`-Rpass=.*` (in fact, you can use any valid POSIX regular +`-Rpass=.*` (in fact, you can use any valid POSIX regular expression). However, do not expect a report from every transformation made by the compiler. Optimization remarks do not really make sense outside of the major transformations (e.g., inlining, vectorization, @@ -585,7 +585,7 @@ Current limitations 2. Some source locations are not displayed correctly. The front end has a more detailed source location tracking than the locations included in the debug info (e.g., the front end can locate code inside macro - expansions). However, the locations used by :option:`-Rpass` are + expansions). However, the locations used by `-Rpass` are translated from debug annotations. That translation can be lossy, which results in some remarks having no location information. @@ -711,16 +711,19 @@ also allows you to push and pop the current warning state. This is particularly useful when writing a header file that will be compiled by other people, because you don't know what warning flags they build with. -In the below example :option:`-Wmultichar` is ignored for only a single line of -code, after which the diagnostics return to whatever state had previously +In the below example :option:`-Wextra-tokens` is ignored for only a single line +of code, after which the diagnostics return to whatever state had previously existed. .. code-block:: c - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wmultichar" + #if foo + #endif foo // warning: extra tokens at end of #endif directive - char b = 'df'; // no warning. + #pragma clang diagnostic ignored "-Wextra-tokens" + + #if foo + #endif foo // no warning #pragma clang diagnostic pop @@ -772,13 +775,15 @@ the pragma onwards within the same file. .. code-block:: c - char a = 'xy'; // warning + #if foo + #endif foo // warning: extra tokens at end of #endif directive #pragma clang system_header - char b = 'ab'; // no warning + #if foo + #endif foo // no warning -The :option:`--system-header-prefix=` and :option:`--no-system-header-prefix=` +The `--system-header-prefix=` and `--no-system-header-prefix=` command-line arguments can be used to override whether subsets of an include path are treated as system headers. When the name in a ``#include`` directive is found within a header search path and starts with a system prefix, the @@ -847,7 +852,7 @@ Generating a PCH File ^^^^^^^^^^^^^^^^^^^^^ To generate a PCH file using Clang, one invokes Clang with the -:option:`-x -header` option. This mirrors the interface in GCC +`-x -header` option. This mirrors the interface in GCC for generating PCH files: .. code-block:: console @@ -910,7 +915,7 @@ location. Building a relocatable precompiled header requires two additional arguments. First, pass the ``--relocatable-pch`` flag to indicate that the resulting PCH file should be relocatable. Second, pass -:option:`-isysroot /path/to/build`, which makes all includes for your library +`-isysroot /path/to/build`, which makes all includes for your library relative to the build directory. For example: .. code-block:: console @@ -920,9 +925,9 @@ relative to the build directory. For example: When loading the relocatable PCH file, the various headers used in the PCH file are found from the system header root. For example, ``mylib.h`` can be found in ``/usr/include/mylib.h``. If the headers are installed -in some other system root, the :option:`-isysroot` option can be used provide +in some other system root, the `-isysroot` option can be used provide a different system root from which the headers will be based. For -example, :option:`-isysroot /Developer/SDKs/MacOSX10.4u.sdk` will look for +example, `-isysroot /Developer/SDKs/MacOSX10.4u.sdk` will look for ``mylib.h`` in ``/Developer/SDKs/MacOSX10.4u.sdk/usr/include/mylib.h``. Relocatable precompiled headers are intended to be used in a limited @@ -986,6 +991,8 @@ are listed below. **-f[no-]sanitize-recover=check1,check2,...** +**-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 of this kind is detected and error report is printed. @@ -1038,6 +1045,11 @@ are listed below. Enable simple code coverage in addition to certain sanitizers. See :doc:`SanitizerCoverage` for more details. +**-f[no-]sanitize-stats** + + Enable simple statistics gathering for the enabled sanitizers. + See :doc:`SanitizerStats` for more details. + .. option:: -fsanitize-undefined-trap-on-error Deprecated alias for ``-fsanitize-trap=undefined``. @@ -1048,6 +1060,25 @@ are listed below. the behavior of sanitizers in the ``cfi`` group to allow checking of cross-DSO virtual and indirect calls. +.. option:: -ffast-math + + Enable fast-math mode. This defines the ``__FAST_MATH__`` preprocessor + macro, and lets the compiler make aggressive, potentially-lossy assumptions + about floating-point math. These include: + + * Floating-point math obeys regular algebraic rules for real numbers (e.g. + ``+`` and ``*`` are associative, ``x/y == x * (1/y)``, and + ``(a + b) * c == a * c + b * c``), + * operands to floating-point operations are not equal to ``NaN`` and + ``Inf``, and + * ``+0`` and ``-0`` are interchangeable. + +.. option:: -fwhole-program-vtables + + Enable whole-program vtable optimizations, such as single-implementation + devirtualization and virtual constant propagation, for classes with + :doc:`hidden LTO visibility `. Requires ``-flto``. + .. option:: -fno-assume-sane-operator-new Don't assume that the C++'s new operator is sane. @@ -1114,6 +1145,16 @@ are listed below. This option restricts the generated code to use general registers only. This only applies to the AArch64 architecture. +.. option:: -mcompact-branches=[values] + + Control the usage of compact branches for MIPSR6. + + Valid values are: ``never``, ``optimal`` and ``always``. + The default value is ``optimal`` which generates compact branches + when a delay slot cannot be filled. ``never`` disables the usage of + compact branches and ``always`` generates compact branches whenever + possible. + **-f[no-]max-type-align=[number]** Instruct the code generator to not enforce a higher alignment than the given number (of bytes) when accessing memory via an opaque pointer or reference. @@ -1461,19 +1502,21 @@ instrumentation: profile. As you make changes to your code, clang may no longer be able to use the profile data. It will warn you when this happens. -Profile generation and use can also be controlled by the GCC-compatible flags -``-fprofile-generate`` and ``-fprofile-use``. Although these flags are -semantically equivalent to their GCC counterparts, they *do not* handle -GCC-compatible profiles. They are only meant to implement GCC's semantics -with respect to profile creation and use. +Profile generation using an alternative instrumentation method can be +controlled by the GCC-compatible flags ``-fprofile-generate`` and +``-fprofile-use``. Although these flags are semantically equivalent to +their GCC counterparts, they *do not* handle GCC-compatible profiles. +They are only meant to implement GCC's semantics with respect to +profile creation and use. .. option:: -fprofile-generate[=] - Without any other arguments, ``-fprofile-generate`` behaves identically to - ``-fprofile-instr-generate``. When given a directory name, it generates the - profile file ``default.profraw`` in the directory named ``dirname``. If - ``dirname`` does not exist, it will be created at runtime. The environment - variable ``LLVM_PROFILE_FILE`` can be used to override the directory and + The ``-fprofile-generate`` and ``-fprofile-generate=`` flags will use + an alterantive instrumentation method for profile generation. When + given a directory name, it generates the profile file + ``default.profraw`` in the directory named ``dirname``. If ``dirname`` + does not exist, it will be created at runtime. The environment variable + ``LLVM_PROFILE_FILE`` can be used to override the directory and filename for the profile file at runtime. For example, .. code-block:: console @@ -1689,10 +1732,6 @@ GCC extensions not implemented yet clang tries to be compatible with gcc as much as possible, but some gcc extensions are not implemented yet: -- clang does not support #pragma weak (`bug - 3679 `_). Due to the uses - described in the bug, this is likely to be implemented at some point, - at least partially. - clang does not support decimal floating point types (``_Decimal32`` and friends) or fixed-point types (``_Fract`` and friends); nobody has expressed interest in these features yet, so it's hard to say when @@ -1710,9 +1749,6 @@ extensions are not implemented yet: ... local_function(1); -- clang does not support global register variables; this is unlikely to - be implemented soon because it requires additional LLVM backend - support. - clang does not support static initialization of flexible array members. This appears to be a rarely used extension, but could be implemented pending user demand. @@ -1757,13 +1793,11 @@ Intentionally unsupported GCC extensions Microsoft extensions -------------------- -clang has some experimental support for extensions from Microsoft Visual -C++; to enable it, use the ``-fms-extensions`` command-line option. This is -the default for Windows targets. Note that the support is incomplete. -Some constructs such as ``dllexport`` on classes are ignored with a warning, -and others such as `Microsoft IDL annotations -`_ are silently -ignored. +clang has support for many extensions from Microsoft Visual C++. To enable these +extensions, use the ``-fms-extensions`` command-line option. This is the default +for Windows targets. Clang does not implement every pragma or declspec provided +by MSVC, but the popular ones, such as ``__declspec(dllexport)`` and ``#pragma +comment(lib)`` are well supported. clang has a ``-fms-compatibility`` flag that makes clang accept enough invalid C++ to be able to parse most Microsoft headers. For example, it @@ -1776,23 +1810,14 @@ for Windows targets. definitions until the end of a translation unit. This flag is enabled by default for Windows targets. -- clang allows setting ``_MSC_VER`` with ``-fmsc-version=``. It defaults to - 1700 which is the same as Visual C/C++ 2012. Any number is supported - and can greatly affect what Windows SDK and c++stdlib headers clang - can compile. -- clang does not support the Microsoft extension where anonymous record - members can be declared using user defined typedefs. -- clang supports the Microsoft ``#pragma pack`` feature for controlling - record layout. GCC also contains support for this feature, however - where MSVC and GCC are incompatible clang follows the MSVC - definition. -- clang supports the Microsoft ``#pragma comment(lib, "foo.lib")`` feature for - automatically linking against the specified library. Currently this feature - only works with the Visual C++ linker. -- clang supports the Microsoft ``#pragma comment(linker, "/flag:foo")`` feature - for adding linker flags to COFF object files. The user is responsible for - ensuring that the linker understands the flags. -- clang defaults to C++11 for Windows targets. +For compatibility with existing code that compiles with MSVC, clang defines the +``_MSC_VER`` and ``_MSC_FULL_VER`` macros. These default to the values of 1800 +and 180000000 respectively, making clang look like an early release of Visual +C++ 2013. The ``-fms-compatibility-version=`` flag overrides these values. It +accepts a dotted version tuple, such as 19.00.23506. Changing the MSVC +compatibility version makes clang behave more like that version of MSVC. For +example, ``-fms-compatibility-version=19`` will enable C++14 features and define +``char16_t`` and ``char32_t`` as builtin types. .. _cxx: @@ -1849,8 +1874,8 @@ directives, ``depend`` clause for ``#pragma omp task`` directive (except for array sections), ``#pragma omp cancel`` and ``#pragma omp cancellation point`` directives, and ``#pragma omp taskgroup`` directive. -Use :option:`-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with -:option:`-fno-openmp`. +Use `-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with +`-fno-openmp`. Controlling implementation limits --------------------------------- @@ -1859,7 +1884,7 @@ Controlling implementation limits Controls code generation for OpenMP threadprivate variables. In presence of this option all threadprivate variables are generated the same way as thread - local variables, using TLS support. If :option:`-fno-openmp-use-tls` + local variables, using TLS support. If `-fno-openmp-use-tls` is provided or target does not support TLS, code generation for threadprivate variables relies on OpenMP runtime library. @@ -1883,7 +1908,7 @@ On ``x86_64-mingw32``, passing i128(by value) is incompatible with the Microsoft x64 calling convention. You might need to tweak ``WinX86_64ABIInfo::classify()`` in lib/CodeGen/TargetInfo.cpp. -For the X86 target, clang supports the :option:`-m16` command line +For the X86 target, clang supports the `-m16` command line argument which enables 16-bit code output. This is broadly similar to using ``asm(".code16gcc")`` with the GNU toolchain. The generated code and the ABI remains 32-bit but the assembler emits instructions @@ -2019,8 +2044,9 @@ with a warning. For example: To suppress warnings about unused arguments, use the ``-Qunused-arguments`` option. -Options that are not known to clang-cl will cause errors. If they are spelled with a -leading ``/``, they will be mistaken for a filename: +Options that are not known to clang-cl will be ignored by default. Use the +``-Werror=unknown-argument`` option in order to treat them as errors. If these +options are spelled with a leading ``/``, they will be mistaken for a filename: :: @@ -2036,6 +2062,8 @@ Execute ``clang-cl /?`` to see a list of supported options: CL.EXE COMPATIBILITY OPTIONS: /? Display available options /arch: Set architecture for code generation + /Brepro- Emit an object file which cannot be reproduced over time + /Brepro Emit an object file which can be reproduced over time /C Don't discard comments when preprocessing /c Compile only /D Define macro @@ -2054,16 +2082,26 @@ Execute ``clang-cl /?`` to see a list of supported options: /fp:fast /fp:precise /fp:strict + /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 /GR- Disable emission of RTTI data /GR Enable emission of RTTI data + /Gr Set __fastcall as a default calling convention + /GS- Disable buffer security check + /GS Enable buffer security check /Gs Set stack probe size + /Gv Set __vectorcall as a default calling convention /Gw- Don't put each data item in its own section /Gw Put each data item in its own section + /GX- Enable exception handling + /GX Enable exception handling /Gy- Don't put each function in its own section /Gy Put each function in its own section + /Gz Set __stdcall as a default calling convention /help Display available options + /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 @@ -2073,20 +2111,18 @@ 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 - /Ob0 Disable inlining /Od Disable optimization /Oi- Disable use of builtin functions /Oi Enable use of builtin functions /Os Optimize for size /Ot Optimize for speed - /Oy- Disable frame pointer omission - /Oy Enable frame pointer omission /O Optimization level /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 /showIncludes Print info about included files to stderr + /std: Language standard to compile for /TC Treat all source files as C /Tc Specify a C source file /TP Treat all source files as C++ @@ -2105,10 +2141,13 @@ Execute ``clang-cl /?`` to see a list of supported options: /W2 Enable -Wall /W3 Enable -Wall /W4 Enable -Wall and -Wextra - /Wall Enable -Wall + /Wall Enable -Wall and -Wextra /WX- Do not treat warnings as errors /WX Treat warnings as errors /w Disable all warnings + /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:sizedDealloc- Disable C++14 sized global deallocation functions /Zc:sizedDealloc Enable C++14 sized global deallocation functions @@ -2117,6 +2156,7 @@ 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 + /Zd Emit debug line number tables only /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 @@ -2133,8 +2173,10 @@ Execute ``clang-cl /?`` to see a list of supported options: -fms-compatibility-version= Dot-separated value representing the 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)) + -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)) -fno-sanitize-coverage= Disable specified features of coverage instrumentation for Sanitizers -fno-sanitize-recover= @@ -2151,6 +2193,8 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize= Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks -gcodeview Generate CodeView debug information + -gline-tables-only Emit debug line number tables only + -miamcu Use Intel MCU ABI -mllvm Additional arguments to forward to LLVM's option processing -Qunused-arguments Don't emit warning for unused driver arguments -R Enable the specified remark diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst index 771e39fc439..bfa3142efbd 100644 --- a/docs/analyzer/DebugChecks.rst +++ b/docs/analyzer/DebugChecks.rst @@ -162,6 +162,41 @@ ExprInspection checks } while(0); // expected-warning{{SYMBOL DEAD}} +- void clang_analyzer_explain(a single argument of any type); + + This function explains the value of its argument in a human-readable manner + in the warning message. You can make as many overrides of its prototype + in the test code as necessary to explain various integral, pointer, + or even record-type values. + + Example usage:: + + void clang_analyzer_explain(int); + void clang_analyzer_explain(void *); + + void foo(int param, void *ptr) { + clang_analyzer_explain(param); // expected-warning{{argument 'param'}} + if (!ptr) + clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}} + } + +- size_t clang_analyzer_getExtent(void *); + + This function returns the value that represents the extent of a memory region + pointed to by the argument. This value is often difficult to obtain otherwise, + because no valid code that produces this value. However, it may be useful + for testing purposes, to see how well does the analyzer model region extents. + + Example usage:: + + void foo() { + int x, *y; + size_t xs = clang_analyzer_getExtent(&x); + clang_analyzer_explain(xs); // expected-warning{{'4'}} + size_t ys = clang_analyzer_getExtent(&y); + clang_analyzer_explain(ys); // expected-warning{{'8'}} + } + Statistics ========== diff --git a/docs/analyzer/Makefile b/docs/analyzer/Makefile deleted file mode 100644 index 14f5e60246d..00000000000 --- a/docs/analyzer/Makefile +++ /dev/null @@ -1,155 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -default: html - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ClangStaticAnalyzer.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ClangStaticAnalyzer.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/ClangStaticAnalyzer" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ClangStaticAnalyzer" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/analyzer/conf.py b/docs/analyzer/conf.py index 1514708c0d5..afbfbee6f37 100644 --- a/docs/analyzer/conf.py +++ b/docs/analyzer/conf.py @@ -12,6 +12,7 @@ # serve to show the default. import sys, os +from datetime import date # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -41,16 +42,16 @@ # General information about the project. project = u'Clang Static Analyzer' -copyright = u'2013-2014, Analyzer Team' +copyright = u'2013-%d, Analyzer Team' % date.today().year # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '3.4' +version = '3.9' # The full version, including alpha/beta/rc tags. -release = '3.4' +release = '3.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/doxygen.intro b/docs/doxygen-mainpage.dox similarity index 56% rename from docs/doxygen.intro rename to docs/doxygen-mainpage.dox index accab72bd08..2fd34f04de7 100644 --- a/docs/doxygen.intro +++ b/docs/doxygen-mainpage.dox @@ -1,15 +1,15 @@ -/// @mainpage clang +/// \mainpage clang /// -/// @section main_intro Introduction +/// \section main_intro Introduction /// Welcome to the clang project. /// -/// This documentation describes the @b internal software that makes -/// up clang, not the @b external use of clang. There are no instructions -/// here on how to use clang, only the APIs that make up the software. For -/// usage instructions, please see the programmer's guide or reference +/// This documentation describes the **internal** software that makes +/// up clang, not the **external** use of clang. There are no instructions +/// here on how to use clang, only the APIs that make up the software. For +/// usage instructions, please see the programmer's guide or reference /// manual. /// -/// @section main_caveat Caveat -/// This documentation is generated directly from the source code with doxygen. +/// \section main_caveat Caveat +/// This documentation is generated directly from the source code with doxygen. /// Since clang is constantly under active development, what you're about to /// read is out of date! diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in index f6c7cba6d39..c96ab49ba0f 100644 --- a/docs/doxygen.cfg.in +++ b/docs/doxygen.cfg.in @@ -745,7 +745,7 @@ WARN_LOGFILE = INPUT = @abs_srcdir@/../include \ @abs_srcdir@/../lib \ - @abs_srcdir@/doxygen.intro + @abs_srcdir@/doxygen-mainpage.dox # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1791,18 +1791,6 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size @@ -1949,7 +1937,7 @@ PREDEFINED = EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an +# remove all references to function-like macros that are alone on a line, have an # all uppercase name, and do not end with a semicolon. Such function macros are # typically used for boiler-plate code, and will confuse the parser if not # removed. diff --git a/docs/index.rst b/docs/index.rst index a0a70c0e61e..296054766d6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -28,9 +28,12 @@ Using Clang as a Compiler DataFlowSanitizer LeakSanitizer SanitizerCoverage + SanitizerStats SanitizerSpecialCaseList ControlFlowIntegrity + LTOVisibility SafeStack + SourceBasedCodeCoverage Modules MSVCCompatibility CommandGuide/index @@ -75,6 +78,7 @@ Design Documents DriverInternals PTHInternals PCHInternals + ItaniumMangleAbiTags Indices and tables diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py old mode 100644 new mode 100755 index 9ecff049c96..45540405de9 --- a/docs/tools/dump_ast_matchers.py +++ b/docs/tools/dump_ast_matchers.py @@ -47,7 +47,7 @@ def link_if_exists(m): except: doxygen_probes[url] = False if doxygen_probes[url]: - return r'Matcher<%s>' % (url, name) + return r'Matcher<%s>' % (url, name) else: return m.group(0) text = re.sub( @@ -83,6 +83,11 @@ def strip_doxygen(comment): """Returns the given comment without \-escaped words.""" # If there is only a doxygen keyword in the line, delete the whole line. comment = re.sub(r'^\\[^\s]+\n', r'', comment, flags=re.M) + + # If there is a doxygen \see command, change the \see prefix into "See also:". + # FIXME: it would be better to turn this into a link to the target instead. + comment = re.sub(r'\\see', r'See also:', comment) + # Delete the doxygen command and the following whitespace. comment = re.sub(r'\\[^\s]+\s+', r'', comment) return comment @@ -90,7 +95,7 @@ def strip_doxygen(comment): def unify_arguments(args): """Gets rid of anything the user doesn't care about in the argument list.""" args = re.sub(r'internal::', r'', args) - args = re.sub(r'const\s+', r'', args) + args = re.sub(r'const\s+(.*)&', r'\1 ', args) args = re.sub(r'&', r' ', args) args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args) return args @@ -226,7 +231,7 @@ def act_on_decl(declaration, comment, allowed_types): m = re.match(r"""^\s*AST_MATCHER(_P)?(.?)(?:_OVERLOAD)?\( (?:\s*([^\s,]+)\s*,)? \s*([^\s,]+)\s* - (?:,\s*([^\s,]+)\s* + (?:,\s*([^,]+)\s* ,\s*([^\s,]+)\s*)? (?:,\s*([^\s,]+)\s* ,\s*([^\s,]+)\s*)? @@ -259,6 +264,16 @@ def act_on_decl(declaration, comment, allowed_types): add_matcher('*', name, 'Matcher<*>', comment) return + # Parse Variadic functions. + m = re.match( + r"""^.*internal::VariadicFunction\s*<\s*([^,]+),\s*([^,]+),\s*[^>]+>\s* + ([a-zA-Z]*)\s*=\s*{.*};$""", + declaration, flags=re.X) + if m: + result, arg, name = m.groups()[:3] + add_matcher(result, name, '%s, ..., %s' % (arg, arg), comment) + return + # Parse Variadic operator matchers. m = re.match( r"""^.*VariadicOperatorMatcherFunc\s*<\s*([^,]+),\s*([^\s>]+)\s*>\s* @@ -358,11 +373,11 @@ def sort_table(matcher_type, matcher_map): reference = open('../LibASTMatchersReference.html').read() reference = re.sub(r'', - '%s', reference, flags=re.S) % node_matcher_table + node_matcher_table, reference, flags=re.S) reference = re.sub(r'', - '%s', reference, flags=re.S) % narrowing_matcher_table + narrowing_matcher_table, reference, flags=re.S) reference = re.sub(r'', - '%s', reference, flags=re.S) % traversal_matcher_table + traversal_matcher_table, reference, flags=re.S) with open('../LibASTMatchersReference.html', 'wb') as output: output.write(reference) diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py index b61d2017d05..6e149394981 100755 --- a/docs/tools/dump_format_style.py +++ b/docs/tools/dump_format_style.py @@ -4,11 +4,13 @@ # Run from the directory in which this file is located to update the docs. import collections +import os import re import urllib2 -FORMAT_STYLE_FILE = '../../include/clang/Format/Format.h' -DOC_FILE = '../ClangFormatStyleOptions.rst' +CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..') +FORMAT_STYLE_FILE = os.path.join(CLANG_DIR, 'include/clang/Format/Format.h') +DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormatStyleOptions.rst') def substitute(text, tag, contents): @@ -77,7 +79,7 @@ def __str__(self): class EnumValue: def __init__(self, name, comment): self.name = name - self.comment = comment.strip() + self.comment = comment def __str__(self): return '* ``%s`` (in configuration: ``%s``)\n%s' % ( @@ -86,8 +88,12 @@ def __str__(self): doxygen2rst(indent(self.comment, 2))) def clean_comment_line(line): - if line == '/// \\code': - return '\n.. code-block:: c++\n\n' + match = re.match(r'^/// \\code(\{.(\w+)\})?$', line) + if match: + lang = match.groups()[1] + if not lang: + lang = 'c++' + return '\n.. code-block:: %s\n\n' % lang if line == '/// \\endcode': return '' return line[4:] + '\n' diff --git a/emscripten-version.txt b/emscripten-version.txt index 29eea173874..dc4e162b4c0 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -"1.36.6" +"1.36.7" diff --git a/examples/AnnotateFunctions/AnnotateFunctions.cpp b/examples/AnnotateFunctions/AnnotateFunctions.cpp new file mode 100644 index 00000000000..375f18f8e09 --- /dev/null +++ b/examples/AnnotateFunctions/AnnotateFunctions.cpp @@ -0,0 +1,88 @@ +//===- AnnotateFunctions.cpp ----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Example clang plugin which adds an annotation to every function in +// translation units that start with #pragma enable_annotate. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/LexDiagnostic.h" +using namespace clang; + +namespace { + +static bool EnableAnnotate = false; +static bool HandledDecl = false; + +class AnnotateFunctionsConsumer : public ASTConsumer { +public: + bool HandleTopLevelDecl(DeclGroupRef DG) override { + HandledDecl = true; + if (!EnableAnnotate) + return true; + for (auto D : DG) + if (FunctionDecl *FD = dyn_cast(D)) + FD->addAttr(AnnotateAttr::CreateImplicit(FD->getASTContext(), + "example_annotation")); + return true; + } +}; + +class AnnotateFunctionsAction : public PluginASTAction { +public: + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef) override { + return llvm::make_unique(); + } + + bool ParseArgs(const CompilerInstance &CI, + const std::vector &args) override { + return true; + } + + PluginASTAction::ActionType getActionType() override { + return AddBeforeMainAction; + } +}; + +class PragmaAnnotateHandler : public PragmaHandler { +public: + PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { } + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &PragmaTok) override { + + Token Tok; + PP.LexUnexpandedToken(Tok); + if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + + if (HandledDecl) { + DiagnosticsEngine &D = PP.getDiagnostics(); + unsigned ID = D.getCustomDiagID( + DiagnosticsEngine::Error, + "#pragma enable_annotate not allowed after declarations"); + D.Report(PragmaTok.getLocation(), ID); + } + + EnableAnnotate = true; + } +}; + +} + +static FrontendPluginRegistry::Add +X("annotate-fns", "annotate functions"); + +static PragmaHandlerRegistry::Add +Y("enable_annotate","enable annotation"); diff --git a/examples/AnnotateFunctions/CMakeLists.txt b/examples/AnnotateFunctions/CMakeLists.txt new file mode 100644 index 00000000000..cf564d527d6 --- /dev/null +++ b/examples/AnnotateFunctions/CMakeLists.txt @@ -0,0 +1,11 @@ +add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp) + +if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) + target_link_libraries(AnnotateFunctions PRIVATE + clangAST + clangBasic + clangFrontend + clangLex + LLVMSupport + ) +endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5d4b5fcdb0f..8c2654840a9 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory(analyzer-plugin) endif() add_subdirectory(clang-interpreter) add_subdirectory(PrintFunctionNames) +add_subdirectory(AnnotateFunctions) diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 index d8d902874ae..00000000000 --- a/examples/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- examples/Makefile -----------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := .. - -PARALLEL_DIRS := analyzer-plugin clang-interpreter PrintFunctionNames - -include $(CLANG_LEVEL)/Makefile diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt index e700281ab48..5a00d5036fb 100644 --- a/examples/PrintFunctionNames/CMakeLists.txt +++ b/examples/PrintFunctionNames/CMakeLists.txt @@ -12,7 +12,7 @@ endif() add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp) if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) - target_link_libraries(PrintFunctionNames ${cmake_2_8_12_PRIVATE} + target_link_libraries(PrintFunctionNames PRIVATE clangAST clangBasic clangFrontend diff --git a/examples/PrintFunctionNames/Makefile b/examples/PrintFunctionNames/Makefile deleted file mode 100644 index 5865098bd30..00000000000 --- a/examples/PrintFunctionNames/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -##===- examples/PrintFunctionNames/Makefile ----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME = PrintFunctionNames - -# If we don't need RTTI or EH, there's no reason to export anything -# from the plugin. -ifneq ($(REQUIRES_RTTI), 1) -ifneq ($(REQUIRES_EH), 1) -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/PrintFunctionNames.exports -endif -endif - -LINK_LIBS_IN_SHARED = 0 -LOADABLE_MODULE = 1 - -include $(CLANG_LEVEL)/Makefile - -ifeq ($(OS),Darwin) - LDFLAGS=-Wl,-undefined,dynamic_lookup -endif diff --git a/examples/analyzer-plugin/CMakeLists.txt b/examples/analyzer-plugin/CMakeLists.txt index 1788d6c5cac..0d5b2754caf 100644 --- a/examples/analyzer-plugin/CMakeLists.txt +++ b/examples/analyzer-plugin/CMakeLists.txt @@ -1,7 +1,8 @@ -add_llvm_loadable_module(SampleAnalyzerPlugin MainCallChecker.cpp) +set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/SampleAnalyzerPlugin.exports) +add_llvm_loadable_module(SampleAnalyzerPlugin MainCallChecker.cpp PLUGIN_TOOL clang) if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN)) - target_link_libraries(SampleAnalyzerPlugin ${cmake_2_8_12_PRIVATE} + target_link_libraries(SampleAnalyzerPlugin PRIVATE clangAnalysis clangAST clangStaticAnalyzerCore diff --git a/examples/analyzer-plugin/Makefile b/examples/analyzer-plugin/Makefile deleted file mode 100644 index 8b83bef9245..00000000000 --- a/examples/analyzer-plugin/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -##===- examples/analyzer-plugin/Makefile -------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME = SampleAnalyzerPlugin - -LINK_LIBS_IN_SHARED = 0 -LOADABLE_MODULE = 1 - -include $(CLANG_LEVEL)/Makefile - -ifeq ($(OS),Darwin) - LDFLAGS=-Wl,-undefined,dynamic_lookup -endif diff --git a/examples/analyzer-plugin/SampleAnalyzerPlugin.exports b/examples/analyzer-plugin/SampleAnalyzerPlugin.exports new file mode 100644 index 00000000000..8d9ff882cfb --- /dev/null +++ b/examples/analyzer-plugin/SampleAnalyzerPlugin.exports @@ -0,0 +1,2 @@ +clang_registerCheckers +clang_analyzerAPIVersionString diff --git a/examples/clang-interpreter/Makefile b/examples/clang-interpreter/Makefile deleted file mode 100644 index 2eff90b32b0..00000000000 --- a/examples/clang-interpreter/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -##===- examples/clang-interpreter/Makefile -----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. - -TOOLNAME = clang-interpreter -NO_INSTALL = 1 - -# No plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -LINK_COMPONENTS := mcjit interpreter nativecodegen bitreader bitwriter irreader \ - ipo linker selectiondag asmparser instrumentation objcarcopts option -USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a clangCodeGen.a \ - clangParse.a clangSema.a clangStaticAnalyzerFrontend.a \ - clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \ - clangAnalysis.a clangRewrite.a clangRewriteFrontend.a \ - clangEdit.a clangAST.a clangLex.a clangBasic.a LLVMCore.a \ - LLVMExecutionEngine.a LLVMMC.a LLVMMCJIT.a LLVMRuntimeDyld.a \ - LLVMObject.a LLVMSupport.a LLVMProfileData.a - -include $(CLANG_LEVEL)/Makefile diff --git a/include/Makefile b/include/Makefile deleted file mode 100644 index 79b9adfb728..00000000000 --- a/include/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -CLANG_LEVEL := .. -DIRS := clang clang-c - -include $(CLANG_LEVEL)/Makefile diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 09e21608263..13db2085ba6 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 32 +#define CINDEX_VERSION_MINOR 35 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -326,7 +326,7 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file); * * \param tu the translation unit * - * \param file_name the name of the file. +* \param file_name the name of the file. * * \returns the file handle for the named file in the translation unit \p tu, * or a NULL file handle if the file was not a part of this translation unit. @@ -1208,7 +1208,18 @@ enum CXTranslationUnit_Flags { * trades runtime on the first parse (serializing the preamble takes time) for * reduced runtime on the second parse (can now reuse the preamble). */ - CXTranslationUnit_CreatePreambleOnFirstParse = 0x100 + CXTranslationUnit_CreatePreambleOnFirstParse = 0x100, + + /** + * \brief Do not stop processing when fatal errors are encountered. + * + * When fatal errors are encountered while parsing a translation unit, + * semantic analysis is typically stopped early when compiling code. A common + * source for fatal errors are unresolvable include files. For the + * purposes of an IDE, this is undesirable behavior and as much information + * as possible should be reported. Use this flag to enable this behavior. + */ + CXTranslationUnit_KeepGoing = 0x200 }; /** @@ -1921,7 +1932,7 @@ enum CXCursorKind { */ CXCursor_CXXDeleteExpr = 135, - /** \brief A unary expression. + /** \brief A unary expression. (noexcept, sizeof, or other traits) */ CXCursor_UnaryExpr = 136, @@ -2003,7 +2014,11 @@ enum CXCursorKind { */ CXCursor_OMPArraySectionExpr = 147, - CXCursor_LastExpr = CXCursor_OMPArraySectionExpr, + /** \brief Represents an @available(...) check. + */ + CXCursor_ObjCAvailabilityCheckExpr = 148, + + CXCursor_LastExpr = CXCursor_ObjCAvailabilityCheckExpr, /* Statements */ CXCursor_FirstStmt = 200, @@ -2270,11 +2285,47 @@ enum CXCursorKind { */ CXCursor_OMPTaskLoopSimdDirective = 259, - /** \brief OpenMP distribute directive. + /** \brief OpenMP distribute directive. */ CXCursor_OMPDistributeDirective = 260, - CXCursor_LastStmt = CXCursor_OMPDistributeDirective, + /** \brief OpenMP target enter data directive. + */ + CXCursor_OMPTargetEnterDataDirective = 261, + + /** \brief OpenMP target exit data directive. + */ + CXCursor_OMPTargetExitDataDirective = 262, + + /** \brief OpenMP target parallel directive. + */ + CXCursor_OMPTargetParallelDirective = 263, + + /** \brief OpenMP target parallel for directive. + */ + CXCursor_OMPTargetParallelForDirective = 264, + + /** \brief OpenMP target update directive. + */ + CXCursor_OMPTargetUpdateDirective = 265, + + /** \brief OpenMP distribute parallel for directive. + */ + CXCursor_OMPDistributeParallelForDirective = 266, + + /** \brief OpenMP distribute parallel for simd directive. + */ + CXCursor_OMPDistributeParallelForSimdDirective = 267, + + /** \brief OpenMP distribute simd directive. + */ + CXCursor_OMPDistributeSimdDirective = 268, + + /** \brief OpenMP target parallel for simd directive. + */ + CXCursor_OMPTargetParallelForSimdDirective = 269, + + CXCursor_LastStmt = CXCursor_OMPTargetParallelForSimdDirective, /** * \brief Cursor that represents the translation unit itself. @@ -2328,8 +2379,12 @@ enum CXCursorKind { */ CXCursor_ModuleImportDecl = 600, CXCursor_TypeAliasTemplateDecl = 601, + /** + * \brief A static_assert or _Static_assert node + */ + CXCursor_StaticAssert = 602, CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, - CXCursor_LastExtraDecl = CXCursor_TypeAliasTemplateDecl, + CXCursor_LastExtraDecl = CXCursor_StaticAssert, /** * \brief A code completion overload candidate. @@ -2430,6 +2485,11 @@ CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind); */ CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind); +/** + * \brief Determine whether the given cursor has any attributes. + */ +CINDEX_LINKAGE unsigned clang_Cursor_hasAttrs(CXCursor C); + /** * \brief Determine whether the given cursor kind represents an invalid * cursor. @@ -2526,7 +2586,7 @@ typedef struct CXPlatformAvailability { * \brief A string that describes the platform for which this structure * provides availability information. * - * Possible values are "ios" or "macosx". + * Possible values are "ios" or "macos". */ CXString Platform; /** @@ -2897,6 +2957,7 @@ enum CXTypeKind { CXType_ObjCId = 27, CXType_ObjCClass = 28, CXType_ObjCSel = 29, + CXType_Float128 = 30, CXType_FirstBuiltin = CXType_Void, CXType_LastBuiltin = CXType_ObjCSel, @@ -2918,7 +2979,14 @@ enum CXTypeKind { CXType_VariableArray = 115, CXType_DependentSizedArray = 116, CXType_MemberPointer = 117, - CXType_Auto = 118 + CXType_Auto = 118, + + /** + * \brief Represents a type that was referred to using an elaborated type keyword. + * + * E.g., struct S, or via a qualified name, e.g., N::M::type, or both. + */ + CXType_Elaborated = 119 }; /** @@ -2938,6 +3006,9 @@ enum CXCallingConv { CXCallingConv_X86_64Win64 = 10, CXCallingConv_X86_64SysV = 11, CXCallingConv_X86VectorCall = 12, + CXCallingConv_Swift = 13, + CXCallingConv_PreserveMost = 14, + CXCallingConv_PreserveAll = 15, CXCallingConv_Invalid = 100, CXCallingConv_Unexposed = 200 @@ -3169,6 +3240,24 @@ CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T); */ CINDEX_LINKAGE unsigned clang_isConstQualifiedType(CXType T); +/** + * \brief Determine whether a CXCursor that is a macro, is + * function like. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isMacroFunctionLike(CXCursor C); + +/** + * \brief Determine whether a CXCursor that is a macro, is a + * builtin one. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isMacroBuiltin(CXCursor C); + +/** + * \brief Determine whether a CXCursor that is a function declaration, is an + * inline declaration. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isFunctionInlined(CXCursor C); + /** * \brief Determine whether a CXType has the "volatile" qualifier set, * without looking through typedefs that may have added "volatile" at @@ -3198,6 +3287,11 @@ CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T); */ CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C); +/** + * Returns the Objective-C type encoding for the specified CXType. + */ +CINDEX_LINKAGE CXString clang_Type_getObjCEncoding(CXType type); + /** * \brief Retrieve the spelling of a given CXTypeKind. */ @@ -3281,6 +3375,13 @@ CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T); */ CINDEX_LINKAGE long long clang_getArraySize(CXType T); +/** + * \brief Retrieve the type named by the qualified-id. + * + * If a non-elaborated type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T); + /** * \brief List the possible error codes for \c clang_Type_getSizeOf, * \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and @@ -3612,8 +3713,8 @@ typedef enum CXChildVisitResult * Visits the children of a cursor using the specified block. Behaves * identically to clang_visitChildren() in all other respects. */ -unsigned clang_visitChildrenWithBlock(CXCursor parent, - CXCursorVisitorBlock block); +CINDEX_LINKAGE unsigned clang_visitChildrenWithBlock(CXCursor parent, + CXCursorVisitorBlock block); # endif #endif @@ -3834,7 +3935,8 @@ typedef enum { CXObjCPropertyAttr_atomic = 0x100, CXObjCPropertyAttr_weak = 0x200, CXObjCPropertyAttr_strong = 0x400, - CXObjCPropertyAttr_unsafe_unretained = 0x800 + CXObjCPropertyAttr_unsafe_unretained = 0x800, + CXObjCPropertyAttr_class = 0x1000 } CXObjCPropertyAttrKind; /** @@ -4015,11 +4117,36 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, * @{ */ +/** + * \brief Determine if a C++ constructor is a converting constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C); + +/** + * \brief Determine if a C++ constructor is a copy constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C); + +/** + * \brief Determine if a C++ constructor is the default constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C); + +/** + * \brief Determine if a C++ constructor is a move constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C); + /** * \brief Determine if a C++ field is declared 'mutable'. */ CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C); +/** + * \brief Determine if a C++ method is declared '= default'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); + /** * \brief Determine if a C++ member function or member function template is * pure virtual. @@ -4900,7 +5027,7 @@ CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void); * Note that the column should point just after the syntactic construct that * initiated code completion, and not in the middle of a lexical token. * - * \param unsaved_files the Tiles that have not yet been saved to disk + * \param unsaved_files the Files that have not yet been saved to disk * but may be required for parsing or code completion, including the * contents of those files. The contents and name of these files (as * specified by CXUnsavedFile) are copied when necessary, so the @@ -5077,6 +5204,59 @@ CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu, CXInclusionVisitor visitor, CXClientData client_data); +typedef enum { + CXEval_Int = 1 , + CXEval_Float = 2, + CXEval_ObjCStrLiteral = 3, + CXEval_StrLiteral = 4, + CXEval_CFStr = 5, + CXEval_Other = 6, + + CXEval_UnExposed = 0 + +} CXEvalResultKind ; + +/** + * \brief Evaluation result of a cursor + */ +typedef void * CXEvalResult; + +/** + * \brief If cursor is a statement declaration tries to evaluate the + * statement and if its variable, tries to evaluate its initializer, + * into its corresponding type. + */ +CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C); + +/** + * \brief Returns the kind of the evaluated result. + */ +CINDEX_LINKAGE CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E); + +/** + * \brief Returns the evaluation result as integer if the + * kind is Int. + */ +CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E); + +/** + * \brief Returns the evaluation result as double if the + * kind is double. + */ +CINDEX_LINKAGE double clang_EvalResult_getAsDouble(CXEvalResult E); + +/** + * \brief Returns the evaluation result as a constant string if the + * kind is other than Int or float. User must not free this pointer, + * instead call clang_EvalResult_dispose on the CXEvalResult returned + * by clang_Cursor_Evaluate. + */ +CINDEX_LINKAGE const char* clang_EvalResult_getAsStr(CXEvalResult E); + +/** + * \brief Disposes the created Eval memory. + */ +CINDEX_LINKAGE void clang_EvalResult_dispose(CXEvalResult E); /** * @} */ @@ -5150,7 +5330,7 @@ enum CXVisitorResult { CXVisit_Continue }; -typedef struct { +typedef struct CXCursorAndRangeVisitor { void *context; enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange); } CXCursorAndRangeVisitor; diff --git a/include/clang-c/Makefile b/include/clang-c/Makefile deleted file mode 100644 index b29e29ea1ef..00000000000 --- a/include/clang-c/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -CLANG_LEVEL := ../.. -DIRS := - -include $(CLANG_LEVEL)/Makefile - -IntIncludeDir = $(DESTDIR)$(PROJ_internal_prefix)/include - -install-local:: - $(Echo) Installing Clang C API include files - $(Verb) $(MKDIR) $(IntIncludeDir) - $(Verb) if test -d "$(PROJ_SRC_DIR)" ; then \ - cd $(PROJ_SRC_DIR)/.. && \ - for hdr in `find clang-c -type f '!' '(' -name '*~' \ - -o -name '.#*' -o -name '*.in' -o -name '*.txt' \ - -o -name 'Makefile' -o -name '*.td' ')' -print \ - | grep -v CVS | grep -v .svn | grep -v .dir` ; do \ - instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \ - done ; \ - fi -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) - $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang-c" ; then \ - cd $(PROJ_OBJ_ROOT)/tools/clang/include && \ - for hdr in `find clang-c -type f '!' '(' -name 'Makefile' ')' -print \ - | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \ - instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \ - done ; \ - fi -endif diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h index c830aa3d787..554e0c0c6d0 100644 --- a/include/clang/ARCMigrate/ARCMTActions.h +++ b/include/clang/ARCMigrate/ARCMTActions.h @@ -22,7 +22,7 @@ class CheckAction : public WrapperFrontendAction { bool BeginInvocation(CompilerInstance &CI) override; public: - CheckAction(FrontendAction *WrappedAction); + CheckAction(std::unique_ptr WrappedAction); }; class ModifyAction : public WrapperFrontendAction { @@ -30,7 +30,7 @@ class ModifyAction : public WrapperFrontendAction { bool BeginInvocation(CompilerInstance &CI) override; public: - ModifyAction(FrontendAction *WrappedAction); + ModifyAction(std::unique_ptr WrappedAction); }; class MigrateSourceAction : public ASTFrontendAction { @@ -49,7 +49,8 @@ class MigrateAction : public WrapperFrontendAction { bool BeginInvocation(CompilerInstance &CI) override; public: - MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, + MigrateAction(std::unique_ptr WrappedAction, + StringRef migrateDir, StringRef plistOut, bool emitPremigrationARCErrors); }; @@ -61,8 +62,8 @@ class ObjCMigrateAction : public WrapperFrontendAction { FileRemapper Remapper; CompilerInstance *CompInst; public: - ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, - unsigned migrateAction); + ObjCMigrateAction(std::unique_ptr WrappedAction, + StringRef migrateDir, unsigned migrateAction); protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index b2730e46222..0b1f0068fa6 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -55,9 +55,9 @@ class ASTConsumer { /// \returns true to continue parsing, or false to abort parsing. virtual bool HandleTopLevelDecl(DeclGroupRef D); - /// \brief This callback is invoked each time an inline method definition is - /// completed. - virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {} + /// \brief This callback is invoked each time an inline (method or friend) + /// function definition in a class is completed. + virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {} /// HandleInterestingDecl - Handle the specified interesting declaration. This /// is called by the AST reader when deserializing things that might interest @@ -94,21 +94,6 @@ class ASTConsumer { /// The default implementation passes it to HandleTopLevelDecl. virtual void HandleImplicitImportDecl(ImportDecl *D); - /// \brief Handle a pragma that appends to Linker Options. Currently this - /// only exists to support Microsoft's #pragma comment(linker, "/foo"). - virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {} - - /// \brief Handle a pragma that emits a mismatch identifier and value to the - /// object file for the linker to work with. Currently, this only exists to - /// support Microsoft's #pragma detect_mismatch. - virtual void HandleDetectMismatch(llvm::StringRef Name, - llvm::StringRef Value) {} - - /// \brief Handle a dependent library created by a pragma in the source. - /// Currently this only exists to support Microsoft's - /// #pragma comment(lib, "/foo"). - virtual void HandleDependentLibrary(llvm::StringRef Lib) {} - /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. @@ -120,6 +105,10 @@ class ASTConsumer { /// modified by the introduction of an implicit zero initializer. virtual void CompleteTentativeDefinition(VarDecl *D) {} + /// \brief Callback invoked when an MSInheritanceAttr has been attached to a + /// CXXRecordDecl. + virtual void AssignInheritanceModel(CXXRecordDecl *RD) {} + /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this // variable has been instantiated. virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {} diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index abf92948bb4..1d223f47a9a 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -36,6 +36,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" @@ -128,6 +129,8 @@ class ASTContext : public RefCountedBase { llvm::FoldingSet PackExpansionTypes; mutable llvm::FoldingSet ObjCObjectTypes; mutable llvm::FoldingSet ObjCObjectPointerTypes; + mutable llvm::FoldingSet + DependentUnaryTransformTypes; mutable llvm::FoldingSet AutoTypes; mutable llvm::FoldingSet AtomicTypes; llvm::FoldingSet AttributedTypes; @@ -212,9 +215,6 @@ class ASTContext : public RefCountedBase { /// \brief The typedef for the __uint128_t type. mutable TypedefDecl *UInt128Decl; - /// \brief The typedef for the __float128 stub type. - mutable TypeDecl *Float128StubDecl; - /// \brief The typedef for the target specific predefined /// __builtin_va_list type. mutable TypedefDecl *BuiltinVaListDecl; @@ -243,6 +243,9 @@ class ASTContext : public RefCountedBase { QualType ObjCClassRedefinitionType; QualType ObjCSelRedefinitionType; + /// The identifier 'bool'. + mutable IdentifierInfo *BoolName = nullptr; + /// The identifier 'NSObject'. IdentifierInfo *NSObjectName = nullptr; @@ -252,9 +255,13 @@ class ASTContext : public RefCountedBase { /// The identifier '__make_integer_seq'. mutable IdentifierInfo *MakeIntegerSeqName = nullptr; + /// The identifier '__type_pack_element'. + mutable IdentifierInfo *TypePackElementName = nullptr; + QualType ObjCConstantStringType; - mutable RecordDecl *CFConstantStringTypeDecl; - + mutable RecordDecl *CFConstantStringTagDecl; + mutable TypedefDecl *CFConstantStringTypeDecl; + mutable QualType ObjCSuperType; QualType ObjCNSStringType; @@ -392,8 +399,8 @@ class ASTContext : public RefCountedBase { /// \brief Side-table of mangling numbers for declarations which rarely /// need them (like static local vars). - llvm::DenseMap MangleNumbers; - llvm::DenseMap StaticLocalNumbers; + llvm::MapVector MangleNumbers; + llvm::MapVector StaticLocalNumbers; /// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. @@ -406,6 +413,7 @@ class ASTContext : public RefCountedBase { TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; + mutable BuiltinTemplateDecl *TypePackElementDecl; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -817,6 +825,9 @@ class ASTContext : public RefCountedBase { overridden_methods_end(const CXXMethodDecl *Method) const; unsigned overridden_methods_size(const CXXMethodDecl *Method) const; + typedef llvm::iterator_range + overridden_method_range; + overridden_method_range overridden_methods(const CXXMethodDecl *Method) const; /// \brief Note that the given C++ \p Method overrides the given \p /// Overridden method. @@ -876,6 +887,7 @@ class ASTContext : public RefCountedBase { ExternCContextDecl *getExternCContextDecl() const; BuiltinTemplateDecl *getMakeIntegerSeqDecl() const; + BuiltinTemplateDecl *getTypePackElementDecl() const; // Builtin Types. CanQualType VoidTy; @@ -889,20 +901,19 @@ class ASTContext : public RefCountedBase { CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty; CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; - CanQualType FloatTy, DoubleTy, LongDoubleTy; + CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; + CanQualType Float128ComplexTy; CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; - CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; - CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy; - CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy; - CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy; - CanQualType OCLImage3dTy; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + CanQualType SingletonId; +#include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy; CanQualType OMPArraySectionTy; @@ -966,9 +977,6 @@ class ASTContext : public RefCountedBase { /// \brief Retrieve the declaration for the 128-bit unsigned integer type. TypedefDecl *getUInt128Decl() const; - /// \brief Retrieve the declaration for a 128-bit float stub type. - TypeDecl *getFloat128StubType() const; - //===--------------------------------------------------------------------===// // Type Constructors //===--------------------------------------------------------------------===// @@ -1229,13 +1237,12 @@ class ASTContext : public RefCountedBase { TemplateTypeParmDecl *ParmDecl = nullptr) const; QualType getTemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, QualType Canon = QualType()) const; - QualType getCanonicalTemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs) const; + QualType + getCanonicalTemplateSpecializationType(TemplateName T, + ArrayRef Args) const; QualType getTemplateSpecializationType(TemplateName T, const TemplateArgumentListInfo &Args, @@ -1260,11 +1267,9 @@ class ASTContext : public RefCountedBase { NestedNameSpecifier *NNS, const IdentifierInfo *Name, const TemplateArgumentListInfo &Args) const; - QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, - const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args) const; + QualType getDependentTemplateSpecializationType( + ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, + const IdentifierInfo *Name, ArrayRef Args) const; QualType getPackExpansionType(QualType Pattern, Optional NumExpansions); @@ -1381,10 +1386,12 @@ class ASTContext : public RefCountedBase { /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { if (CFConstantStringTypeDecl) - return getTagDeclType(CFConstantStringTypeDecl); + return getTypedefType(CFConstantStringTypeDecl); return QualType(); } void setCFConstantStringType(QualType T); + TypedefDecl *getCFConstantStringDecl() const; + RecordDecl *getCFConstantStringTagDecl() const; // This setter/getter represents the ObjC type for an NSConstantString. void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl); @@ -1458,12 +1465,25 @@ class ASTContext : public RefCountedBase { return NSCopyingName; } + /// Retrieve the identifier 'bool'. + IdentifierInfo *getBoolName() const { + if (!BoolName) + BoolName = &Idents.get("bool"); + return BoolName; + } + IdentifierInfo *getMakeIntegerSeqName() const { if (!MakeIntegerSeqName) MakeIntegerSeqName = &Idents.get("__make_integer_seq"); return MakeIntegerSeqName; } + IdentifierInfo *getTypePackElementName() const { + if (!TypePackElementName) + TypePackElementName = &Idents.get("__type_pack_element"); + return TypePackElementName; + } + /// \brief Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; QualType getObjCInstanceType() { @@ -2257,7 +2277,7 @@ class ASTContext : public RefCountedBase { QualType mergeObjCGCQualifiers(QualType, QualType); - bool FunctionTypesMatchOnNSConsumedAttrs( + bool doFunctionTypesMatchOnExtParameterInfos( const FunctionProtoType *FromFunctionType, const FunctionProtoType *ToFunctionType); @@ -2508,7 +2528,21 @@ class ASTContext : public RefCountedBase { /// \brief Returns true if this is an inline-initialized static data member /// which is treated as a definition for MSVC compatibility. bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const; - + + enum class InlineVariableDefinitionKind { + None, ///< Not an inline variable. + Weak, ///< Weak definition of inline variable. + WeakUnknown, ///< Weak for now, might become strong later in this TU. + Strong ///< Strong definition. + }; + /// \brief Determine whether a definition of this inline variable should + /// be treated as a weak or strong definition. For compatibility with + /// C++14 and before, for a constexpr static data member, if there is an + /// out-of-line declaration of the member, we may promote it from weak to + /// strong. + InlineVariableDefinitionKind + getInlineVariableDefinitionKind(const VarDecl *VD) const; + private: const ASTRecordLayout & getObjCLayout(const ObjCInterfaceDecl *D, diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index ee48955ca63..e116abaef79 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -23,6 +23,7 @@ namespace clang { class ASTContext; + class CXXCtorInitializer; class Decl; class DeclContext; class DiagnosticsEngine; @@ -204,6 +205,14 @@ namespace clang { /// \returns the equivalent file ID in the source manager of the "to" /// context. FileID Import(FileID); + + /// \brief Import the given C++ constructor initializer from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent initializer in the "to" context. + CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); + + /// \brief Import the definition of the given declaration, including all of /// the declarations it contains. diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index cf3b55d7b2c..e2d184d654e 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -17,6 +17,7 @@ namespace clang { class Attr; class ClassTemplateDecl; class ClassTemplateSpecializationDecl; + class ConstructorUsingShadowDecl; class CXXDestructorDecl; class CXXRecordDecl; class Decl; @@ -107,6 +108,14 @@ class ASTMutationListener { /// \param D the declaration marked OpenMP threadprivate. virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {} + /// \brief A declaration is marked as OpenMP declaretarget which was not + /// previously marked as declaretarget. + /// + /// \param D the declaration marked OpenMP declaretarget. + /// \param Attr the added attribute. + virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) {} + /// \brief A definition has been made visible by being redefined locally. /// /// \param D The definition that was previously not visible. diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index dcaac802c11..ad301b14829 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -62,7 +62,9 @@ class ASTNodeKind { /// \} /// \brief Returns \c true if \c this and \c Other represent the same kind. - bool isSame(ASTNodeKind Other) const; + bool isSame(ASTNodeKind Other) const { + return KindId != NKI_None && KindId == Other.KindId; + } /// \brief Returns \c true only for the default \c ASTNodeKind() bool isNone() const { return KindId == NKI_None; } diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 8b80e9f6396..a94b161a04b 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -20,6 +20,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" @@ -50,11 +51,11 @@ class Attr { /// An index into the spelling list of an /// attribute defined in Attr.td file. unsigned SpellingListIndex : 4; - bool Inherited : 1; - bool IsPackExpansion : 1; - bool Implicit : 1; - bool IsLateParsed : 1; - bool DuplicatesAllowed : 1; + unsigned Inherited : 1; + unsigned IsPackExpansion : 1; + unsigned Implicit : 1; + unsigned IsLateParsed : 1; + unsigned DuplicatesAllowed : 1; void *operator new(size_t bytes) LLVM_NOEXCEPT { llvm_unreachable("Attrs cannot be allocated with regular 'new'."); @@ -118,6 +119,19 @@ class Attr { bool duplicatesAllowed() const { return DuplicatesAllowed; } }; +class StmtAttr : public Attr { +protected: + StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, + bool IsLateParsed, bool DuplicatesAllowed) + : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {} + +public: + static bool classof(const Attr *A) { + return A->getKind() >= attr::FirstStmtAttr && + A->getKind() <= attr::LastStmtAttr; + } +}; + class InheritableAttr : public Attr { protected: InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, @@ -129,7 +143,8 @@ class InheritableAttr : public Attr { // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - return A->getKind() <= attr::LAST_INHERITABLE; + return A->getKind() >= attr::FirstInheritableAttr && + A->getKind() <= attr::LastInheritableAttr; } }; @@ -143,12 +158,41 @@ class InheritableParamAttr : public InheritableAttr { public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - // Relies on relative order of enum emission with respect to MS inheritance - // attrs. - return A->getKind() <= attr::LAST_INHERITABLE_PARAM; + return A->getKind() >= attr::FirstInheritableParamAttr && + A->getKind() <= attr::LastInheritableParamAttr; } }; +/// A parameter attribute which changes the argument-passing ABI rule +/// for the parameter. +class ParameterABIAttr : public InheritableParamAttr { +protected: + ParameterABIAttr(attr::Kind AK, SourceRange R, + unsigned SpellingListIndex, bool IsLateParsed, + bool DuplicatesAllowed) + : InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed, + DuplicatesAllowed) {} + +public: + ParameterABI getABI() const { + switch (getKind()) { + case attr::SwiftContext: + return ParameterABI::SwiftContext; + case attr::SwiftErrorResult: + return ParameterABI::SwiftErrorResult; + case attr::SwiftIndirectResult: + return ParameterABI::SwiftIndirectResult; + default: + llvm_unreachable("bad parameter ABI attribute kind"); + } + } + + static bool classof(const Attr *A) { + return A->getKind() >= attr::FirstParameterABIAttr && + A->getKind() <= attr::LastParameterABIAttr; + } +}; + #include "clang/AST/Attrs.inc" inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h new file mode 100644 index 00000000000..5ed83137845 --- /dev/null +++ b/include/clang/AST/Availability.h @@ -0,0 +1,63 @@ +//===--- Availability.h - Classes for availability --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This files defines some classes that implement availability checking. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_AVAILABILITY_H +#define LLVM_CLANG_AST_AVAILABILITY_H + +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + +/// \brief One specifier in an @available expression. +/// +/// \code +/// @available(macos 10.10, *) +/// \endcode +/// +/// Here, 'macos 10.10' and '*' both map to an instance of this type. +/// +class AvailabilitySpec { + /// Represents the version that this specifier requires. If the host OS + /// version is greater than or equal to Version, the @available will evaluate + /// to true. + VersionTuple Version; + + /// Name of the platform that Version corresponds to. + StringRef Platform; + + SourceLocation BeginLoc, EndLoc; + +public: + AvailabilitySpec(VersionTuple Version, StringRef Platform, + SourceLocation BeginLoc, SourceLocation EndLoc) + : Version(Version), Platform(Platform), BeginLoc(BeginLoc), + EndLoc(EndLoc) {} + + /// This constructor is used when representing the '*' case. + AvailabilitySpec(SourceLocation StarLoc) + : BeginLoc(StarLoc), EndLoc(StarLoc) {} + + VersionTuple getVersion() const { return Version; } + StringRef getPlatform() const { return Platform; } + SourceLocation getBeginLoc() const { return BeginLoc; } + SourceLocation getEndLoc() const { return EndLoc; } + + /// Returns true when this represents the '*' case. + bool isOtherPlatformSpec() const { return Version.empty(); } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h index da538e3566a..66af023c828 100644 --- a/include/clang/AST/BaseSubobject.h +++ b/include/clang/AST/BaseSubobject.h @@ -15,13 +15,12 @@ #define LLVM_CLANG_AST_BASESUBOBJECT_H #include "clang/AST/CharUnits.h" +#include "clang/AST/DeclCXX.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/type_traits.h" namespace clang { - class CXXRecordDecl; - // BaseSubobject - Uniquely identifies a direct or indirect base class. // Stores both the base class decl and the offset from the most derived class to // the base class. Used for vtable and VTT generation. diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index a08a6839024..c0c6819280d 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy) // 'long double' FLOATING_TYPE(LongDouble, LongDoubleTy) +// '__float128' +FLOATING_TYPE(Float128, Float128Ty) + //===- Language-specific types --------------------------------------------===// // This is the type of C++0x 'nullptr'. @@ -154,20 +157,6 @@ BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy) // type is a typedef of a PointerType to this. BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy) -// OpenCL image types. -BUILTIN_TYPE(OCLImage1d, OCLImage1dTy) -BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy) -BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy) -BUILTIN_TYPE(OCLImage2d, OCLImage2dTy) -BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy) -BUILTIN_TYPE(OCLImage2dDepth, OCLImage2dDepthTy) -BUILTIN_TYPE(OCLImage2dArrayDepth, OCLImage2dArrayDepthTy) -BUILTIN_TYPE(OCLImage2dMSAA, OCLImage2dMSAATy) -BUILTIN_TYPE(OCLImage2dArrayMSAA, OCLImage2dArrayMSAATy) -BUILTIN_TYPE(OCLImage2dMSAADepth, OCLImage2dMSAADepthTy) -BUILTIN_TYPE(OCLImage2dArrayMSAADepth, OCLImage2dArrayMSAADepthTy) -BUILTIN_TYPE(OCLImage3d, OCLImage3dTy) - // OpenCL sampler_t. BUILTIN_TYPE(OCLSampler, OCLSamplerTy) diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index b25800bfedb..77510afeec1 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -484,6 +484,9 @@ struct CanProxyAdaptor LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR( + ArrayRef, getExtParameterInfos) CanQualType getParamType(unsigned i) const { return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i)); } diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 1d22bccd2e8..564c8ec9b9e 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -133,7 +133,7 @@ namespace clang { /// Test whether this is a multiple of the other value. /// /// Among other things, this promises that - /// self.RoundUpToAlignment(N) will just return self. + /// self.alignTo(N) will just return self. bool isMultipleOf(CharUnits N) const { return (*this % N) == 0; } @@ -142,9 +142,17 @@ namespace clang { CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); } + CharUnits &operator*= (QuantityType N) { + Quantity *= N; + return *this; + } CharUnits operator/ (QuantityType N) const { return CharUnits(Quantity / N); } + CharUnits &operator/= (QuantityType N) { + Quantity /= N; + return *this; + } QuantityType operator/ (const CharUnits &Other) const { return Quantity / Other.Quantity; } @@ -170,12 +178,11 @@ namespace clang { /// getQuantity - Get the raw integer representation of this quantity. QuantityType getQuantity() const { return Quantity; } - /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is + /// alignTo - Returns the next integer (mod 2**64) that is /// greater than or equal to this quantity and is a multiple of \p Align. /// Align must be non-zero. - CharUnits RoundUpToAlignment(const CharUnits &Align) const { - return CharUnits(llvm::RoundUpToAlignment(Quantity, - Align.Quantity)); + CharUnits alignTo(const CharUnits &Align) const { + return CharUnits(llvm::alignTo(Quantity, Align.Quantity)); } /// Given that this is a non-zero alignment value, what is the diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 029c1182f26..109036f9588 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -23,6 +23,7 @@ #include "clang/Basic/Linkage.h" #include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" @@ -103,6 +104,73 @@ class TranslationUnitDecl : public Decl, public DeclContext { } }; +/// \brief Represents a `#pragma comment` line. Always a child of +/// TranslationUnitDecl. +class PragmaCommentDecl final + : public Decl, + private llvm::TrailingObjects { + virtual void anchor(); + + PragmaMSCommentKind CommentKind; + + friend TrailingObjects; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind) + : Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {} + +public: + static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC, + SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind, + StringRef Arg); + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned ArgSize); + + PragmaMSCommentKind getCommentKind() const { return CommentKind; } + + StringRef getArg() const { return getTrailingObjects(); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == PragmaComment; } +}; + +/// \brief Represents a `#pragma detect_mismatch` line. Always a child of +/// TranslationUnitDecl. +class PragmaDetectMismatchDecl final + : public Decl, + private llvm::TrailingObjects { + virtual void anchor(); + + size_t ValueStart; + + friend TrailingObjects; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc, + size_t ValueStart) + : Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {} + +public: + static PragmaDetectMismatchDecl *Create(const ASTContext &C, + TranslationUnitDecl *DC, + SourceLocation Loc, StringRef Name, + StringRef Value); + static PragmaDetectMismatchDecl * + CreateDeserialized(ASTContext &C, unsigned ID, unsigned NameValueSize); + + StringRef getName() const { return getTrailingObjects(); } + StringRef getValue() const { return getTrailingObjects() + ValueStart; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == PragmaDetectMismatch; } +}; + /// \brief Declaration context for names declared as extern "C" in C++. This /// is neither the semantic nor lexical context for such declarations, but is /// used to check for conflicts with other extern "C" declarations. Example: @@ -319,6 +387,7 @@ class NamedDecl : public Decl { NamedDecl *getUnderlyingDecl() { // Fast-path the common case. if (this->getKind() != UsingShadow && + this->getKind() != ConstructorUsingShadow && this->getKind() != ObjCCompatibleAlias && this->getKind() != NamespaceAlias) return this; @@ -813,12 +882,15 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { /// variable; see isARCPseudoStrong() for details. unsigned ARCPseudoStrong : 1; + /// \brief Whether this variable is (C++1z) inline. + unsigned IsInline : 1; + + /// \brief Whether this variable has (C++1z) inline explicitly specified. + unsigned IsInlineSpecified : 1; + /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; - /// \brief Whether this variable is a (C++ Concepts TS) concept. - unsigned IsConcept : 1; - /// \brief Whether this variable is the implicit variable for a lambda /// init-capture. unsigned IsInitCapture : 1; @@ -1037,9 +1109,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { /// definition of a static data member. bool isOutOfLine() const override; - /// \brief If this is a static data member, find its out-of-line definition. - VarDecl *getOutOfLineDefinition(); - /// isFileVarDecl - Returns true for file scoped variable declaration. bool isFileVarDecl() const { Kind K = getKind(); @@ -1185,6 +1254,24 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.ARCPseudoStrong = ps; } + /// Whether this variable is (C++1z) inline. + bool isInline() const { + return isa(this) ? false : NonParmVarDeclBits.IsInline; + } + bool isInlineSpecified() const { + return isa(this) ? false + : NonParmVarDeclBits.IsInlineSpecified; + } + void setInlineSpecified() { + assert(!isa(this)); + NonParmVarDeclBits.IsInline = true; + NonParmVarDeclBits.IsInlineSpecified = true; + } + void setImplicitlyInline() { + assert(!isa(this)); + NonParmVarDeclBits.IsInline = true; + } + /// Whether this variable is (C++11) constexpr. bool isConstexpr() const { return isa(this) ? false : NonParmVarDeclBits.IsConstexpr; @@ -1194,15 +1281,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.IsConstexpr = IC; } - /// Whether this variable is (C++ Concepts TS) concept. - bool isConcept() const { - return isa(this) ? false : NonParmVarDeclBits.IsConcept; - } - void setConcept(bool IC) { - assert(!isa(this)); - NonParmVarDeclBits.IsConcept = IC; - } - /// Whether this variable is the implicit variable for a lambda init-capture. bool isInitCapture() const { return isa(this) ? false : NonParmVarDeclBits.IsInitCapture; @@ -1702,6 +1780,17 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext, return isDefined(Definition); } + /// \brief Get the definition for this declaration. + FunctionDecl *getDefinition() { + const FunctionDecl *Definition; + if (isDefined(Definition)) + return const_cast(Definition); + return nullptr; + } + const FunctionDecl *getDefinition() const { + return const_cast(this)->getDefinition(); + } + /// getBody - Retrieve the body (definition) of the function. The /// function body might be in any of the (re-)declarations of this /// function. The variant that accepts a FunctionDecl pointer will @@ -1896,29 +1985,24 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext, unsigned getBuiltinID() const; - // Iterator access to formal parameters. - unsigned param_size() const { return getNumParams(); } - typedef ParmVarDecl **param_iterator; - typedef ParmVarDecl * const *param_const_iterator; - typedef llvm::iterator_range param_range; - typedef llvm::iterator_range param_const_range; - - param_iterator param_begin() { return param_iterator(ParamInfo); } - param_iterator param_end() { - return param_iterator(ParamInfo + param_size()); - } - param_range params() { return param_range(param_begin(), param_end()); } - - param_const_iterator param_begin() const { - return param_const_iterator(ParamInfo); + // ArrayRef interface to parameters. + ArrayRef parameters() const { + return {ParamInfo, getNumParams()}; } - param_const_iterator param_end() const { - return param_const_iterator(ParamInfo + param_size()); - } - param_const_range params() const { - return param_const_range(param_begin(), param_end()); + MutableArrayRef parameters() { + return {ParamInfo, getNumParams()}; } + // Iterator access to formal parameters. + typedef MutableArrayRef::iterator param_iterator; + typedef ArrayRef::const_iterator param_const_iterator; + bool param_empty() const { return parameters().empty(); } + param_iterator param_begin() { return parameters().begin(); } + param_iterator param_end() { return parameters().end(); } + param_const_iterator param_begin() const { return parameters().begin(); } + param_const_iterator param_end() const { return parameters().end(); } + size_t param_size() const { return parameters().size(); } + /// getNumParams - Return the number of parameters this function must have /// based on its FunctionType. This is the length of the ParamInfo array /// after it has been created. @@ -1936,12 +2020,6 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext, setParams(getASTContext(), NewParamInfo); } - // ArrayRef iterface to parameters. - // FIXME: Should one day replace iterator interface. - ArrayRef parameters() const { - return llvm::makeArrayRef(ParamInfo, getNumParams()); - } - ArrayRef getDeclsInPrototypeScope() const { return DeclsInPrototypeScope; } @@ -1954,6 +2032,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext, unsigned getMinRequiredArguments() const; QualType getReturnType() const { + assert(getType()->getAs() && "Expected a FunctionType!"); return getType()->getAs()->getReturnType(); } @@ -1964,15 +2043,20 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext, /// \brief Determine the type of an expression that calls this function. QualType getCallResultType() const { + assert(getType()->getAs() && "Expected a FunctionType!"); return getType()->getAs()->getCallResultType(getASTContext()); } + /// \brief Returns the WarnUnusedResultAttr that is either declared on this + /// function, or its return type declaration. + const Attr *getUnusedResultAttr() const; + /// \brief Returns true if this function or its return type has the /// warn_unused_result attribute. If the return type has the attribute and /// this function is a method of the return type's class, then false will be /// returned to avoid spurious warnings on member methods such as assignment /// operators. - bool hasUnusedResultAttr() const; + bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; } /// \brief Returns the storage class as written in the source. For the /// computed linkage of symbol, see getLinkage. @@ -2208,7 +2292,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext, /// represent a member of a struct/union/class. class FieldDecl : public DeclaratorDecl, public Mergeable { // FIXME: This can be packed into the bitfields in Decl. - bool Mutable : 1; + unsigned Mutable : 1; mutable unsigned CachedFieldIndex : 31; /// The kinds of value we can store in InitializerOrBitWidth. @@ -2442,34 +2526,33 @@ class IndirectFieldDecl : public ValueDecl, IndirectFieldDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, - NamedDecl **CH, unsigned CHS); + MutableArrayRef CH); public: static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T, NamedDecl **CH, unsigned CHS); + QualType T, llvm::MutableArrayRef CH); static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - typedef NamedDecl * const *chain_iterator; - typedef llvm::iterator_range chain_range; - chain_range chain() const { return chain_range(chain_begin(), chain_end()); } - chain_iterator chain_begin() const { return chain_iterator(Chaining); } - chain_iterator chain_end() const { - return chain_iterator(Chaining + ChainingSize); + typedef ArrayRef::const_iterator chain_iterator; + + ArrayRef chain() const { + return llvm::makeArrayRef(Chaining, ChainingSize); } + chain_iterator chain_begin() const { return chain().begin(); } + chain_iterator chain_end() const { return chain().end(); } unsigned getChainingSize() const { return ChainingSize; } FieldDecl *getAnonField() const { - assert(ChainingSize >= 2); - return cast(Chaining[ChainingSize - 1]); + assert(chain().size() >= 2); + return cast(chain().back()); } VarDecl *getVarDecl() const { - assert(ChainingSize >= 2); - return dyn_cast(*chain_begin()); + assert(chain().size() >= 2); + return dyn_cast(chain().front()); } IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); } @@ -2655,20 +2738,20 @@ class TagDecl /// IsCompleteDefinition - True if this is a definition ("struct foo /// {};"), false if it is a declaration ("struct foo;"). It is not /// a definition until the definition has been fully processed. - bool IsCompleteDefinition : 1; + unsigned IsCompleteDefinition : 1; protected: /// IsBeingDefined - True if this is currently being defined. - bool IsBeingDefined : 1; + unsigned IsBeingDefined : 1; private: /// IsEmbeddedInDeclarator - True if this tag declaration is /// "embedded" (i.e., defined or declared for the very first time) /// in the syntax of a declarator. - bool IsEmbeddedInDeclarator : 1; + unsigned IsEmbeddedInDeclarator : 1; /// \brief True if this tag is free standing, e.g. "struct foo;". - bool IsFreeStanding : 1; + unsigned IsFreeStanding : 1; protected: // These are used by (and only defined for) EnumDecl. @@ -2677,28 +2760,28 @@ class TagDecl /// IsScoped - True if this tag declaration is a scoped enumeration. Only /// possible in C++11 mode. - bool IsScoped : 1; + unsigned IsScoped : 1; /// IsScopedUsingClassTag - If this tag declaration is a scoped enum, /// then this is true if the scoped enum was declared using the class /// tag, false if it was declared with the struct tag. No meaning is /// associated if this tag declaration is not a scoped enum. - bool IsScopedUsingClassTag : 1; + unsigned IsScopedUsingClassTag : 1; /// IsFixed - True if this is an enumeration with fixed underlying type. Only /// possible in C++11, Microsoft extensions, or Objective C mode. - bool IsFixed : 1; + unsigned IsFixed : 1; /// \brief Indicates whether it is possible for declarations of this kind /// to have an out-of-date definition. /// /// This option is only enabled when modules are enabled. - bool MayHaveOutOfDateDef : 1; + unsigned MayHaveOutOfDateDef : 1; /// Has the full definition of this type been required by a use somewhere in /// the TU. - bool IsCompleteDefinitionRequired : 1; + unsigned IsCompleteDefinitionRequired : 1; private: - SourceLocation RBraceLoc; + SourceRange BraceRange; // A struct representing syntactic qualifier info, // to be used for the (uncommon) case of out-of-line declarations. @@ -2760,8 +2843,8 @@ class TagDecl using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; - SourceLocation getRBraceLoc() const { return RBraceLoc; } - void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + SourceRange getBraceRange() const { return BraceRange; } + void setBraceRange(SourceRange R) { BraceRange = R; } /// getInnerLocStart - Return SourceLocation representing start of source /// range ignoring outer template declarations. @@ -3122,6 +3205,10 @@ class EnumDecl : public TagDecl { return isCompleteDefinition() || isFixed(); } + /// \brief Retrieve the enum definition from which this enumeration could + /// be instantiated, if it is an instantiation (rather than a non-template). + EnumDecl *getTemplateInstantiationPattern() const; + /// \brief Returns the enumeration (declared within the template) /// from which this enumeration type was instantiated, or NULL if /// this enumeration was not instantiated from any template. @@ -3452,35 +3539,23 @@ class BlockDecl : public Decl, public DeclContext { void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; } TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; } - // Iterator access to formal parameters. - unsigned param_size() const { return getNumParams(); } - typedef ParmVarDecl **param_iterator; - typedef ParmVarDecl * const *param_const_iterator; - typedef llvm::iterator_range param_range; - typedef llvm::iterator_range param_const_range; - // ArrayRef access to formal parameters. - // FIXME: Should eventual replace iterator access. - ArrayRef parameters() const { - return llvm::makeArrayRef(ParamInfo, param_size()); + ArrayRef parameters() const { + return {ParamInfo, getNumParams()}; } - - bool param_empty() const { return NumParams == 0; } - param_range params() { return param_range(param_begin(), param_end()); } - param_iterator param_begin() { return param_iterator(ParamInfo); } - param_iterator param_end() { - return param_iterator(ParamInfo + param_size()); + MutableArrayRef parameters() { + return {ParamInfo, getNumParams()}; } - param_const_range params() const { - return param_const_range(param_begin(), param_end()); - } - param_const_iterator param_begin() const { - return param_const_iterator(ParamInfo); - } - param_const_iterator param_end() const { - return param_const_iterator(ParamInfo + param_size()); - } + // Iterator access to formal parameters. + typedef MutableArrayRef::iterator param_iterator; + typedef ArrayRef::const_iterator param_const_iterator; + bool param_empty() const { return parameters().empty(); } + param_iterator param_begin() { return parameters().begin(); } + param_iterator param_end() { return parameters().end(); } + param_const_iterator param_begin() const { return parameters().begin(); } + param_const_iterator param_end() const { return parameters().end(); } + size_t param_size() const { return parameters().size(); } unsigned getNumParams() const { return NumParams; } const ParmVarDecl *getParamDecl(unsigned i) const { @@ -3501,22 +3576,12 @@ class BlockDecl : public Decl, public DeclContext { /// Does not include an entry for 'this'. unsigned getNumCaptures() const { return NumCaptures; } - typedef const Capture *capture_iterator; - typedef const Capture *capture_const_iterator; - typedef llvm::iterator_range capture_range; - typedef llvm::iterator_range capture_const_range; + typedef ArrayRef::const_iterator capture_const_iterator; - capture_range captures() { - return capture_range(capture_begin(), capture_end()); - } - capture_const_range captures() const { - return capture_const_range(capture_begin(), capture_end()); - } + ArrayRef captures() const { return {Captures, NumCaptures}; } - capture_iterator capture_begin() { return Captures; } - capture_iterator capture_end() { return Captures + NumCaptures; } - capture_const_iterator capture_begin() const { return Captures; } - capture_const_iterator capture_end() const { return Captures + NumCaptures; } + capture_const_iterator capture_begin() const { return captures().begin(); } + capture_const_iterator capture_end() const { return captures().end(); } bool capturesCXXThis() const { return CapturesCXXThis; } bool blockMissingReturnType() const { return BlockMissingReturnType; } @@ -3607,6 +3672,14 @@ class CapturedDecl final getParams()[i] = P; } + // ArrayRef interface to parameters. + ArrayRef parameters() const { + return {getParams(), getNumParams()}; + } + MutableArrayRef parameters() { + return {getParams(), getNumParams()}; + } + /// \brief Retrieve the parameter containing captured variables. ImplicitParamDecl *getContextParam() const { assert(ContextParam < NumParams); @@ -3627,9 +3700,6 @@ class CapturedDecl final /// \brief Retrieve an iterator one past the last parameter decl. param_iterator param_end() const { return getParams() + NumParams; } - /// \brief Retrieve an iterator range for the parameter declarations. - param_range params() const { return param_range(param_begin(), param_end()); } - // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Captured; } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 2d6e84a68aa..ec8bb3aaa30 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -52,6 +52,7 @@ struct PrintingPolicy; class RecordDecl; class Stmt; class StoredDeclsMap; +class TemplateDecl; class TranslationUnitDecl; class UsingDirectiveDecl; } @@ -72,13 +73,10 @@ namespace clang { /// /// Note: There are objects tacked on before the *beginning* of Decl /// (and its subclasses) in its Decl::operator new(). Proper alignment -/// of all subclasses (not requiring more than DeclObjAlignment) is +/// of all subclasses (not requiring more than the alignment of Decl) is /// asserted in DeclBase.cpp. -class Decl { +class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl { public: - /// \brief Alignment guaranteed when allocating Decl and any subtypes. - enum { DeclObjAlignment = llvm::AlignOf::Alignment }; - /// \brief Lists the kind of concrete classes of Decl. enum Kind { #define DECL(DERIVED, BASE) DERIVED, @@ -166,7 +164,10 @@ class Decl { /// has been declared outside any function. These act mostly like /// invisible friend declarations, but are also visible to unqualified /// lookup within the scope of the declaring function. - IDNS_LocalExtern = 0x0800 + IDNS_LocalExtern = 0x0800, + + /// This declaration is an OpenMP user defined reduction construction. + IDNS_OMPReduction = 0x1000 }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and @@ -256,7 +257,7 @@ class Decl { SourceLocation Loc; /// DeclKind - This indicates which class this is. - unsigned DeclKind : 8; + unsigned DeclKind : 7; /// InvalidDecl - This indicates a semantic error occurred. unsigned InvalidDecl : 1; @@ -296,7 +297,7 @@ class Decl { unsigned Hidden : 1; /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. - unsigned IdentifierNamespace : 12; + unsigned IdentifierNamespace : 13; /// \brief If 0, we have not computed the linkage of this declaration. /// Otherwise, it is the linkage + 1. @@ -514,8 +515,8 @@ class Decl { bool isImplicit() const { return Implicit; } void setImplicit(bool I = true) { Implicit = I; } - /// \brief Whether this declaration was used, meaning that a definition - /// is required. + /// \brief Whether *any* (re-)declaration of the entity was used, meaning that + /// a definition is required. /// /// \param CheckUsedAttr When true, also consider the "used" attribute /// (in addition to the "used" bit set by \c setUsed()) when determining @@ -525,7 +526,8 @@ class Decl { /// \brief Set whether the declaration is used, in the sense of odr-use. /// /// This should only be used immediately after creating a declaration. - void setIsUsed() { Used = true; } + /// It intentionally doesn't notify any listeners. + void setIsUsed() { getCanonicalDecl()->Used = true; } /// \brief Mark the declaration used, in the sense of odr-use. /// @@ -564,6 +566,13 @@ class Decl { return NextInContextAndBits.getInt() & ModulePrivateFlag; } + /// Return true if this declaration has an attribute which acts as + /// definition of the entity, such as 'alias' or 'ifunc'. + bool hasDefiningAttr() const; + + /// Return this declaration's defining attribute if it has one. + const Attr *getDefiningAttr() const; + protected: /// \brief Specify whether this declaration was marked as being private /// to the module in which it was defined. @@ -895,6 +904,10 @@ class Decl { DeclKind == FunctionTemplate; } + /// \brief If this is a declaration that describes some template, this + /// method returns that template declaration. + TemplateDecl *getDescribedTemplate() const; + /// \brief Returns the function itself, or the templated function if this is a /// function template. FunctionDecl *getAsFunction() LLVM_READONLY; @@ -1117,6 +1130,7 @@ class DeclContextLookupResult { /// ObjCContainerDecl /// LinkageSpecDecl /// BlockDecl +/// OMPDeclareReductionDecl /// class DeclContext { /// DeclKind - This indicates which class this is. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7c54901be3e..66acfee60db 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -16,6 +16,7 @@ #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/Attr.h" #include "clang/AST/Decl.h" @@ -29,6 +30,7 @@ namespace clang { class ClassTemplateDecl; class ClassTemplateSpecializationDecl; +class ConstructorUsingShadowDecl; class CXXBasePath; class CXXBasePaths; class CXXConstructorDecl; @@ -165,13 +167,13 @@ class CXXBaseSpecifier { SourceLocation EllipsisLoc; /// \brief Whether this is a virtual base class or not. - bool Virtual : 1; + unsigned Virtual : 1; /// \brief Whether this is the base of a class (true) or of a struct (false). /// /// This determines the mapping from the access specifier as written in the /// source code to the access specifier used for semantic analysis. - bool BaseOfClass : 1; + unsigned BaseOfClass : 1; /// \brief Access specifier as written in the source code (may be AS_none). /// @@ -181,7 +183,7 @@ class CXXBaseSpecifier { /// \brief Whether the class contains a using declaration /// to inherit the named class's constructors. - bool InheritConstructors : 1; + unsigned InheritConstructors : 1; /// \brief The type of the base class. /// @@ -257,30 +259,6 @@ class CXXBaseSpecifier { TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; } }; -/// \brief A lazy pointer to the definition data for a declaration. -/// FIXME: This is a little CXXRecordDecl-specific that the moment. -template class LazyDefinitionDataPtr { - llvm::PointerUnion DataOrCanonicalDecl; - - LazyDefinitionDataPtr update() { - if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast()) { - if (Canon->isCanonicalDecl()) - Canon->getMostRecentDecl(); - else - // Declaration isn't canonical any more; - // update it and perform path compression. - *this = Canon->getPreviousDecl()->DefinitionData.update(); - } - return *this; - } - -public: - LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {} - LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {} - T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast(); } - T *get() { return update().getNotUpdated(); } -}; - /// \brief Represents a C++ struct/union/class. class CXXRecordDecl : public RecordDecl { @@ -301,30 +279,30 @@ class CXXRecordDecl : public RecordDecl { DefinitionData(CXXRecordDecl *D); /// \brief True if this class has any user-declared constructors. - bool UserDeclaredConstructor : 1; + unsigned UserDeclaredConstructor : 1; /// \brief The user-declared special members which this class has. unsigned UserDeclaredSpecialMembers : 6; /// \brief True when this class is an aggregate. - bool Aggregate : 1; + unsigned Aggregate : 1; /// \brief True when this class is a POD-type. - bool PlainOldData : 1; + unsigned PlainOldData : 1; /// true when this class is empty for traits purposes, /// i.e. has no data members other than 0-width bit-fields, has no /// virtual function/base, and doesn't inherit from a non-empty /// class. Doesn't take union-ness into account. - bool Empty : 1; + unsigned Empty : 1; /// \brief True when this class is polymorphic, i.e., has at /// least one virtual member or derives from a polymorphic class. - bool Polymorphic : 1; + unsigned Polymorphic : 1; /// \brief True when this class is abstract, i.e., has at least /// one pure virtual function, (that can come from a base class). - bool Abstract : 1; + unsigned Abstract : 1; /// \brief True when this class has standard layout. /// @@ -340,58 +318,70 @@ class CXXRecordDecl : public RecordDecl { /// classes with non-static data members, and /// * has no base classes of the same type as the first non-static data /// member. - bool IsStandardLayout : 1; + unsigned IsStandardLayout : 1; /// \brief True when there are no non-empty base classes. /// /// This is a helper bit of state used to implement IsStandardLayout more /// efficiently. - bool HasNoNonEmptyBases : 1; + unsigned HasNoNonEmptyBases : 1; /// \brief True when there are private non-static data members. - bool HasPrivateFields : 1; + unsigned HasPrivateFields : 1; /// \brief True when there are protected non-static data members. - bool HasProtectedFields : 1; + unsigned HasProtectedFields : 1; /// \brief True when there are private non-static data members. - bool HasPublicFields : 1; + unsigned HasPublicFields : 1; /// \brief True if this class (or any subobject) has mutable fields. - bool HasMutableFields : 1; + unsigned HasMutableFields : 1; /// \brief True if this class (or any nested anonymous struct or union) /// has variant members. - bool HasVariantMembers : 1; + unsigned HasVariantMembers : 1; /// \brief True if there no non-field members declared by the user. - bool HasOnlyCMembers : 1; + unsigned HasOnlyCMembers : 1; /// \brief True if any field has an in-class initializer, including those /// within anonymous unions or structs. - bool HasInClassInitializer : 1; + unsigned HasInClassInitializer : 1; /// \brief True if any field is of reference type, and does not have an /// in-class initializer. /// /// In this case, value-initialization of this class is illegal in C++98 /// even if the class has a trivial default constructor. - bool HasUninitializedReferenceMember : 1; + unsigned HasUninitializedReferenceMember : 1; + + /// \brief True if any non-mutable field whose type doesn't have a user- + /// provided default ctor also doesn't have an in-class initializer. + unsigned HasUninitializedFields : 1; + + /// \brief True if there are any member using-declarations that inherit + /// constructors from a base class. + unsigned HasInheritedConstructor : 1; + + /// \brief True if there are any member using-declarations named + /// 'operator='. + unsigned HasInheritedAssignment : 1; /// \brief These flags are \c true if a defaulted corresponding special /// member can't be fully analyzed without performing overload resolution. /// @{ - bool NeedOverloadResolutionForMoveConstructor : 1; - bool NeedOverloadResolutionForMoveAssignment : 1; - bool NeedOverloadResolutionForDestructor : 1; + unsigned NeedOverloadResolutionForMoveConstructor : 1; + unsigned NeedOverloadResolutionForMoveAssignment : 1; + unsigned NeedOverloadResolutionForDestructor : 1; /// @} /// \brief These flags are \c true if an implicit defaulted corresponding /// special member would be defined as deleted. /// @{ - bool DefaultedMoveConstructorIsDeleted : 1; - bool DefaultedMoveAssignmentIsDeleted : 1; - bool DefaultedDestructorIsDeleted : 1; + unsigned DefaultedMoveConstructorIsDeleted : 1; + unsigned DefaultedMoveAssignmentIsDeleted : 1; + unsigned DefaultedDestructorIsDeleted : 1; /// @} /// \brief The trivial special members which this class has, per @@ -411,33 +401,37 @@ class CXXRecordDecl : public RecordDecl { unsigned DeclaredNonTrivialSpecialMembers : 6; /// \brief True when this class has a destructor with no semantic effect. - bool HasIrrelevantDestructor : 1; + unsigned HasIrrelevantDestructor : 1; /// \brief True when this class has at least one user-declared constexpr /// constructor which is neither the copy nor move constructor. - bool HasConstexprNonCopyMoveConstructor : 1; + unsigned HasConstexprNonCopyMoveConstructor : 1; + + /// \brief True if this class has a (possibly implicit) defaulted default + /// constructor. + unsigned HasDefaultedDefaultConstructor : 1; /// \brief True if a defaulted default constructor for this class would /// be constexpr. - bool DefaultedDefaultConstructorIsConstexpr : 1; + unsigned DefaultedDefaultConstructorIsConstexpr : 1; /// \brief True if this class has a constexpr default constructor. /// /// This is true for either a user-declared constexpr default constructor /// or an implicitly declared constexpr default constructor. - bool HasConstexprDefaultConstructor : 1; + unsigned HasConstexprDefaultConstructor : 1; /// \brief True when this class contains at least one non-static data /// member or base class of non-literal or volatile type. - bool HasNonLiteralTypeFieldsOrBases : 1; + unsigned HasNonLiteralTypeFieldsOrBases : 1; /// \brief True when visible conversion functions are already computed /// and are available. - bool ComputedVisibleConversions : 1; + unsigned ComputedVisibleConversions : 1; /// \brief Whether we have a C++11 user-provided default constructor (not /// explicitly deleted or defaulted). - bool UserProvidedDefaultConstructor : 1; + unsigned UserProvidedDefaultConstructor : 1; /// \brief The special members which have been declared for this class, /// either by the user or implicitly. @@ -445,25 +439,25 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether an implicit copy constructor would have a const-qualified /// parameter. - bool ImplicitCopyConstructorHasConstParam : 1; + unsigned ImplicitCopyConstructorHasConstParam : 1; /// \brief Whether an implicit copy assignment operator would have a /// const-qualified parameter. - bool ImplicitCopyAssignmentHasConstParam : 1; + unsigned ImplicitCopyAssignmentHasConstParam : 1; /// \brief Whether any declared copy constructor has a const-qualified /// parameter. - bool HasDeclaredCopyConstructorWithConstParam : 1; + unsigned HasDeclaredCopyConstructorWithConstParam : 1; /// \brief Whether any declared copy assignment operator has either a /// const-qualified reference parameter or a non-reference parameter. - bool HasDeclaredCopyAssignmentWithConstParam : 1; + unsigned HasDeclaredCopyAssignmentWithConstParam : 1; /// \brief Whether this class describes a C++ lambda. - bool IsLambda : 1; + unsigned IsLambda : 1; /// \brief Whether we are currently parsing base specifiers. - bool IsParsingBaseSpecifiers : 1; + unsigned IsParsingBaseSpecifiers : 1; /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -515,16 +509,19 @@ class CXXRecordDecl : public RecordDecl { return getVBasesSlowCase(); } + ArrayRef bases() const { + return llvm::makeArrayRef(getBases(), NumBases); + } + ArrayRef vbases() const { + return llvm::makeArrayRef(getVBases(), NumVBases); + } + private: CXXBaseSpecifier *getBasesSlowCase() const; CXXBaseSpecifier *getVBasesSlowCase() const; }; - typedef LazyDefinitionDataPtr - DefinitionDataPtr; - friend class LazyDefinitionDataPtr; - - mutable DefinitionDataPtr DefinitionData; + struct DefinitionData *DefinitionData; /// \brief Describes a C++ closure type (generated by a lambda expression). struct LambdaDefinitionData : public DefinitionData { @@ -587,8 +584,14 @@ class CXXRecordDecl : public RecordDecl { }; + struct DefinitionData *dataPtr() const { + // Complete the redecl chain (if necessary). + getMostRecentDecl(); + return DefinitionData; + } + struct DefinitionData &data() const { - auto *DD = DefinitionData.get(); + auto *DD = dataPtr(); assert(DD && "queried property of class with no definition"); return *DD; } @@ -596,7 +599,7 @@ class CXXRecordDecl : public RecordDecl { struct LambdaDefinitionData &getLambdaData() const { // No update required: a merged definition cannot change any lambda // properties. - auto *DD = DefinitionData.getNotUpdated(); + auto *DD = DefinitionData; assert(DD && DD->IsLambda && "queried lambda property of non-lambda class"); return static_cast(*DD); } @@ -673,11 +676,13 @@ class CXXRecordDecl : public RecordDecl { } CXXRecordDecl *getDefinition() const { - auto *DD = DefinitionData.get(); + // We only need an update if we don't already know which + // declaration is the definition. + auto *DD = DefinitionData ? DefinitionData : dataPtr(); return DD ? DD->Definition : nullptr; } - bool hasDefinition() const { return DefinitionData.get(); } + bool hasDefinition() const { return DefinitionData || dataPtr(); } static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -1021,7 +1026,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { // An update record can't turn a non-lambda into a lambda. - auto *DD = DefinitionData.getNotUpdated(); + auto *DD = DefinitionData; return DD && DD->IsLambda; } @@ -1136,9 +1141,10 @@ class CXXRecordDecl : public RecordDecl { /// \brief Determine whether this is an empty class in the sense of /// (C++11 [meta.unary.prop]). /// - /// A non-union class is empty iff it has a virtual function, virtual base, - /// data member (other than 0-width bit-field) or inherits from a non-empty - /// class. + /// The CXXRecordDecl is a class type, but not a union type, + /// with no non-static data members other than bit-fields of length 0, + /// no virtual member functions, no virtual base classes, + /// and no base class B for which is_empty::value is false. /// /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } @@ -1270,6 +1276,14 @@ class CXXRecordDecl : public RecordDecl { return !(data().HasTrivialSpecialMembers & SMF_Destructor); } + /// \brief Determine whether declaring a const variable with this type is ok + /// per core issue 253. + bool allowConstDefaultInit() const { + return !data().HasUninitializedFields || + !(data().HasDefaultedDefaultConstructor || + needsImplicitDefaultConstructor()); + } + /// \brief Determine whether this class has a destructor which has no /// semantic effect. /// @@ -1285,6 +1299,18 @@ class CXXRecordDecl : public RecordDecl { return data().HasNonLiteralTypeFieldsOrBases; } + /// \brief Determine whether this class has a using-declaration that names + /// a user-declared base class constructor. + bool hasInheritedConstructor() const { + return data().HasInheritedConstructor; + } + + /// \brief Determine whether this class has a using-declaration that names + /// a base class assignment operator. + bool hasInheritedAssignment() const { + return data().HasInheritedAssignment; + } + /// \brief Determine whether this class is considered trivially copyable per /// (C++11 [class]p6). bool isTriviallyCopyable() const; @@ -1554,6 +1580,14 @@ class CXXRecordDecl : public RecordDecl { static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, DeclarationName Name); + /// \brief Base-class lookup callback that determines whether there exists + /// an OpenMP declare reduction member with the given name. + /// + /// This callback can be used with \c lookupInBases() to find members + /// of the given name within a C++ class hierarchy. + static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, DeclarationName Name); + /// \brief Base-class lookup callback that determines whether there exists /// a member with the given name that can be used in a nested-name-specifier. /// @@ -1690,6 +1724,7 @@ class CXXRecordDecl : public RecordDecl { friend class ASTDeclReader; friend class ASTDeclWriter; + friend class ASTRecordWriter; friend class ASTReader; friend class ASTWriter; }; @@ -1795,6 +1830,8 @@ class CXXMethodDecl : public FunctionDecl { method_iterator begin_overridden_methods() const; method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; + typedef ASTContext::overridden_method_range overridden_method_range; + overridden_method_range overridden_methods() const; /// Returns the parent of this method declaration, which /// is the class in which this method is defined. @@ -1910,15 +1947,15 @@ class CXXCtorInitializer final /// \brief If the initializee is a type, whether that type makes this /// a delegating initialization. - bool IsDelegating : 1; + unsigned IsDelegating : 1; /// \brief If the initializer is a base initializer, this keeps track /// of whether the base is virtual or not. - bool IsVirtual : 1; + unsigned IsVirtual : 1; /// \brief Whether or not the initializer is explicitly written /// in the sources. - bool IsWritten : 1; + unsigned IsWritten : 1; /// If IsWritten is true, then this number keeps track of the textual order /// of this initializer in the original sources, counting from 0; otherwise, @@ -2109,8 +2146,7 @@ class CXXCtorInitializer final assert(I < getNumArrayIndices() && "Out of bounds member array index"); getTrailingObjects()[I] = Index; } - ArrayRef getArrayIndexes() { - assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init"); + ArrayRef getArrayIndices() { return llvm::makeArrayRef(getTrailingObjects(), getNumArrayIndices()); } @@ -2121,6 +2157,23 @@ class CXXCtorInitializer final friend TrailingObjects; }; +/// Description of a constructor that was inherited from a base class. +class InheritedConstructor { + ConstructorUsingShadowDecl *Shadow; + CXXConstructorDecl *BaseCtor; + +public: + InheritedConstructor() : Shadow(), BaseCtor() {} + InheritedConstructor(ConstructorUsingShadowDecl *Shadow, + CXXConstructorDecl *BaseCtor) + : Shadow(Shadow), BaseCtor(BaseCtor) {} + + explicit operator bool() const { return Shadow; } + + ConstructorUsingShadowDecl *getShadowDecl() const { return Shadow; } + CXXConstructorDecl *getConstructor() const { return BaseCtor; } +}; + /// \brief Represents a C++ constructor within a class. /// /// For example: @@ -2131,40 +2184,51 @@ class CXXCtorInitializer final /// explicit X(int); // represented by a CXXConstructorDecl. /// }; /// \endcode -class CXXConstructorDecl : public CXXMethodDecl { +class CXXConstructorDecl final + : public CXXMethodDecl, + private llvm::TrailingObjects { void anchor() override; - /// \brief Whether this constructor declaration has the \c explicit keyword - /// specified. - bool IsExplicitSpecified : 1; /// \name Support for base and member initializers. /// \{ /// \brief The arguments used to initialize the base or member. LazyCXXCtorInitializersPtr CtorInitializers; - unsigned NumCtorInitializers; + unsigned NumCtorInitializers : 30; /// \} + /// \brief Whether this constructor declaration has the \c explicit keyword + /// specified. + unsigned IsExplicitSpecified : 1; + + /// \brief Whether this constructor declaration is an implicitly-declared + /// inheriting constructor. + unsigned IsInheritingConstructor : 1; + CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr) + bool isImplicitlyDeclared, bool isConstexpr, + InheritedConstructor Inherited) : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), - IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr), - NumCtorInitializers(0) { + CtorInitializers(nullptr), NumCtorInitializers(0), + IsExplicitSpecified(isExplicitSpecified), + IsInheritingConstructor((bool)Inherited) { setImplicit(isImplicitlyDeclared); + if (Inherited) + *getTrailingObjects() = Inherited; } public: - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID); - static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isExplicit, - bool isInline, bool isImplicitlyDeclared, - bool isConstexpr); + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, + bool InheritsConstructor); + static CXXConstructorDecl * + Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isExplicit, bool isInline, bool isImplicitlyDeclared, + bool isConstexpr, + InheritedConstructor Inherited = InheritedConstructor()); /// \brief Determine whether this constructor declaration has the /// \c explicit keyword specified. @@ -2311,11 +2375,15 @@ class CXXConstructorDecl : public CXXMethodDecl { /// an object. bool isSpecializationCopyingObject() const; - /// \brief Get the constructor that this inheriting constructor is based on. - const CXXConstructorDecl *getInheritedConstructor() const; + /// \brief Determine whether this is an implicit constructor synthesized to + /// model a call to a constructor inherited from a base class. + bool isInheritingConstructor() const { return IsInheritingConstructor; } - /// \brief Set the constructor that this inheriting constructor is based on. - void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); + /// \brief Get the constructor that this inheriting constructor is based on. + InheritedConstructor getInheritedConstructor() const { + return IsInheritingConstructor ? *getTrailingObjects() + : InheritedConstructor(); + } CXXConstructorDecl *getCanonicalDecl() override { return cast(FunctionDecl::getCanonicalDecl()); @@ -2330,6 +2398,7 @@ class CXXConstructorDecl : public CXXMethodDecl { friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; }; /// \brief Represents a C++ destructor within a class. @@ -2774,18 +2843,6 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable { NamedDecl *UsingOrNextShadow; friend class UsingDecl; - UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc, - UsingDecl *Using, NamedDecl *Target) - : NamedDecl(UsingShadow, DC, Loc, DeclarationName()), - redeclarable_base(C), Underlying(Target), - UsingOrNextShadow(reinterpret_cast(Using)) { - if (Target) { - setDeclName(Target->getDeclName()); - IdentifierNamespace = Target->getIdentifierNamespace(); - } - setImplicit(); - } - typedef Redeclarable redeclarable_base; UsingShadowDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); @@ -2797,11 +2854,16 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable { return getMostRecentDecl(); } +protected: + UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target); + UsingShadowDecl(Kind K, ASTContext &C, EmptyShell); + public: static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target) { - return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target); + return new (C, DC) UsingShadowDecl(UsingShadow, C, DC, Loc, Using, Target); } static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2813,6 +2875,7 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable { using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; UsingShadowDecl *getCanonicalDecl() override { return getFirstDecl(); @@ -2843,7 +2906,125 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable { } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classofKind(Kind K) { return K == Decl::UsingShadow; } + static bool classofKind(Kind K) { + return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// \brief Represents a shadow constructor declaration introduced into a +/// class by a C++11 using-declaration that names a constructor. +/// +/// For example: +/// \code +/// struct Base { Base(int); }; +/// struct Derived { +/// using Base::Base; // creates a UsingDecl and a ConstructorUsingShadowDecl +/// }; +/// \endcode +class ConstructorUsingShadowDecl final : public UsingShadowDecl { + void anchor() override; + + /// \brief If this constructor using declaration inherted the constructor + /// from an indirect base class, this is the ConstructorUsingShadowDecl + /// in the named direct base class from which the declaration was inherited. + ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl; + + /// \brief If this constructor using declaration inherted the constructor + /// from an indirect base class, this is the ConstructorUsingShadowDecl + /// that will be used to construct the unique direct or virtual base class + /// that receives the constructor arguments. + ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl; + + /// \brief \c true if the constructor ultimately named by this using shadow + /// declaration is within a virtual base class subobject of the class that + /// contains this declaration. + unsigned IsVirtual : 1; + + ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target, + bool TargetInVirtualBase) + : UsingShadowDecl(ConstructorUsingShadow, C, DC, Loc, Using, + Target->getUnderlyingDecl()), + NominatedBaseClassShadowDecl( + dyn_cast(Target)), + ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl), + IsVirtual(TargetInVirtualBase) { + // If we found a constructor for a non-virtual base class, but it chains to + // a constructor for a virtual base, we should directly call the virtual + // base constructor instead. + // FIXME: This logic belongs in Sema. + if (!TargetInVirtualBase && NominatedBaseClassShadowDecl && + NominatedBaseClassShadowDecl->constructsVirtualBase()) { + ConstructedBaseClassShadowDecl = + NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl; + IsVirtual = true; + } + } + ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty) + : UsingShadowDecl(ConstructorUsingShadow, C, Empty) {} + +public: + static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target, + bool IsVirtual); + static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + /// Returns the parent of this using shadow declaration, which + /// is the class in which this is declared. + //@{ + const CXXRecordDecl *getParent() const { + return cast(getDeclContext()); + } + CXXRecordDecl *getParent() { + return cast(getDeclContext()); + } + //@} + + /// \brief Get the inheriting constructor declaration for the direct base + /// class from which this using shadow declaration was inherited, if there is + /// one. This can be different for each redeclaration of the same shadow decl. + ConstructorUsingShadowDecl *getNominatedBaseClassShadowDecl() const { + return NominatedBaseClassShadowDecl; + } + + /// \brief Get the inheriting constructor declaration for the base class + /// for which we don't have an explicit initializer, if there is one. + ConstructorUsingShadowDecl *getConstructedBaseClassShadowDecl() const { + return ConstructedBaseClassShadowDecl; + } + + /// \brief Get the base class that was named in the using declaration. This + /// can be different for each redeclaration of this same shadow decl. + CXXRecordDecl *getNominatedBaseClass() const; + + /// \brief Get the base class whose constructor or constructor shadow + /// declaration is passed the constructor arguments. + CXXRecordDecl *getConstructedBaseClass() const { + return cast((ConstructedBaseClassShadowDecl + ? ConstructedBaseClassShadowDecl + : getTargetDecl()) + ->getDeclContext()); + } + + /// \brief Returns \c true if the constructed base class is a virtual base + /// class subobject of this declaration's class. + bool constructsVirtualBase() const { + return IsVirtual; + } + + /// \brief Get the constructor or constructor template in the derived class + /// correspnding to this using shadow declaration, if it has been implicitly + /// declared already. + CXXConstructorDecl *getConstructor() const; + void setConstructor(NamedDecl *Ctor); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ConstructorUsingShadow; } friend class ASTDeclReader; friend class ASTDeclWriter; diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 27b0388007a..5b2e2d9915e 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -57,7 +57,7 @@ class FriendDecl final /// True if this 'friend' declaration is unsupported. Eventually we /// will support every possible friend declaration, but for now we /// silently ignore some and set this flag to authorize all access. - bool UnsupportedFriend : 1; + unsigned UnsupportedFriend : 1; // The number of "outer" template parameter lists in non-templatic // (currently unsupported) friend type declarations, such as diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index f46078f28a7..ad9b5a26b7c 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -351,11 +351,6 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext { typedef llvm::iterator_range param_range; typedef llvm::iterator_range param_const_range; - param_range params() { return param_range(param_begin(), param_end()); } - param_const_range params() const { - return param_const_range(param_begin(), param_end()); - } - param_const_iterator param_begin() const { return param_const_iterator(getParams()); } @@ -689,6 +684,216 @@ class ObjCTypeParamList final friend TrailingObjects; }; +enum class ObjCPropertyQueryKind : uint8_t { + OBJC_PR_query_unknown = 0x00, + OBJC_PR_query_instance, + OBJC_PR_query_class +}; + +/// \brief Represents one property declaration in an Objective-C interface. +/// +/// For example: +/// \code{.mm} +/// \@property (assign, readwrite) int MyProperty; +/// \endcode +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 + // Adding a property should change NumPropertyAttrsBits + }; + + enum { + /// \brief Number of bits fitting all the property attributes. + NumPropertyAttrsBits = 15 + }; + + enum SetterKind { Assign, Retain, Copy, Weak }; + enum PropertyControl { None, Required, Optional }; +private: + SourceLocation AtLoc; // location of \@property + SourceLocation LParenLoc; // location of '(' starting attribute list or null. + QualType DeclType; + TypeSourceInfo *DeclTypeSourceInfo; + unsigned PropertyAttributes : NumPropertyAttrsBits; + unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; + // \@required/\@optional + unsigned PropertyImplementation : 2; + + Selector GetterName; // getter name of NULL if no getter + Selector SetterName; // setter name of NULL if no setter + + ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method + ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method + ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property + + 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()), + GetterMethodDecl(nullptr), SetterMethodDecl(nullptr), + PropertyIvarDecl(nullptr) {} + +public: + static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + IdentifierInfo *Id, SourceLocation AtLocation, + SourceLocation LParenLocation, + QualType T, + TypeSourceInfo *TSI, + PropertyControl propControl = None); + + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } + + TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; } + + QualType getType() const { return DeclType; } + + void setType(QualType T, TypeSourceInfo *TSI) { + DeclType = T; + DeclTypeSourceInfo = TSI; + } + + /// Retrieve the type when this property is used with a specific base object + /// type. + QualType getUsageType(QualType objectType) const; + + PropertyAttributeKind getPropertyAttributes() const { + return PropertyAttributeKind(PropertyAttributes); + } + void setPropertyAttributes(PropertyAttributeKind PRVal) { + PropertyAttributes |= PRVal; + } + void overwritePropertyAttributes(unsigned PRVal) { + PropertyAttributes = PRVal; + } + + PropertyAttributeKind getPropertyAttributesAsWritten() const { + return PropertyAttributeKind(PropertyAttributesAsWritten); + } + + void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { + PropertyAttributesAsWritten = PRVal; + } + + // Helper methods for accessing attributes. + + /// isReadOnly - Return true iff the property has a setter. + bool isReadOnly() const { + return (PropertyAttributes & OBJC_PR_readonly); + } + + /// isAtomic - Return true if the property is atomic. + bool isAtomic() const { + return (PropertyAttributes & OBJC_PR_atomic); + } + + /// isRetaining - Return true if the property retains its value. + bool isRetaining() const { + return (PropertyAttributes & + (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); + } + + bool isInstanceProperty() const { return !isClassProperty(); } + bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; } + ObjCPropertyQueryKind getQueryKind() const { + return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class : + ObjCPropertyQueryKind::OBJC_PR_query_instance; + } + static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) { + return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class : + ObjCPropertyQueryKind::OBJC_PR_query_instance; + } + + /// getSetterKind - Return the method used for doing assignment in + /// 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) + return getType()->isBlockPointerType() ? Copy : Retain; + if (PropertyAttributes & OBJC_PR_retain) + return Retain; + if (PropertyAttributes & OBJC_PR_copy) + return Copy; + if (PropertyAttributes & OBJC_PR_weak) + return Weak; + return Assign; + } + + Selector getGetterName() const { return GetterName; } + void setGetterName(Selector Sel) { GetterName = Sel; } + + Selector getSetterName() const { return SetterName; } + void setSetterName(Selector Sel) { SetterName = Sel; } + + ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } + void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } + + ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } + void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } + + // Related to \@optional/\@required declared in \@protocol + void setPropertyImplementation(PropertyControl pc) { + PropertyImplementation = pc; + } + PropertyControl getPropertyImplementation() const { + return PropertyControl(PropertyImplementation); + } + + void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { + PropertyIvarDecl = Ivar; + } + ObjCIvarDecl *getPropertyIvarDecl() const { + return PropertyIvarDecl; + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(AtLoc, getLocation()); + } + + /// Get the default name of the synthesized ivar. + IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; + + /// Lookup a property by name in the specified DeclContext. + static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, + const IdentifierInfo *propertyID, + ObjCPropertyQueryKind queryKind); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ObjCProperty; } +}; + /// ObjCContainerDecl - Represents a container for method declarations. /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, /// ObjCProtocolDecl, and ObjCImplDecl. @@ -708,7 +913,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext { SourceLocation atStartLoc) : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} - // Iterator access to properties. + // Iterator access to instance/class properties. typedef specific_decl_iterator prop_iterator; typedef llvm::iterator_range> prop_range; @@ -721,6 +926,36 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext { return prop_iterator(decls_end()); } + typedef filtered_decl_iterator + instprop_iterator; + typedef llvm::iterator_range instprop_range; + + instprop_range instance_properties() const { + return instprop_range(instprop_begin(), instprop_end()); + } + instprop_iterator instprop_begin() const { + return instprop_iterator(decls_begin()); + } + instprop_iterator instprop_end() const { + return instprop_iterator(decls_end()); + } + + typedef filtered_decl_iterator + classprop_iterator; + typedef llvm::iterator_range classprop_range; + + classprop_range class_properties() const { + return classprop_range(classprop_begin(), classprop_end()); + } + classprop_iterator classprop_begin() const { + return classprop_iterator(decls_begin()); + } + classprop_iterator classprop_end() const { + return classprop_iterator(decls_end()); + } + // Iterator access to instance/class methods. typedef specific_decl_iterator method_iterator; typedef llvm::iterator_range> @@ -780,9 +1015,12 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext { ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; ObjCPropertyDecl * - FindPropertyDeclaration(const IdentifierInfo *PropertyId) const; + FindPropertyDeclaration(const IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const; - typedef llvm::DenseMap PropertyMap; + typedef llvm::DenseMap, + ObjCPropertyDecl*> PropertyMap; typedef llvm::DenseMap ProtocolPropertyMap; @@ -886,15 +1124,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// \brief Indicates that the contents of this Objective-C class will be /// completed by the external AST source when required. - mutable bool ExternallyCompleted : 1; + mutable unsigned ExternallyCompleted : 1; /// \brief Indicates that the ivar cache does not yet include ivars /// declared in the implementation. - mutable bool IvarListMissingImplementation : 1; + mutable unsigned IvarListMissingImplementation : 1; /// Indicates that this interface decl contains at least one initializer /// marked with the 'objc_designated_initializer' attribute. - bool HasDesignatedInitializers : 1; + unsigned HasDesignatedInitializers : 1; enum InheritedDesignatedInitializersState { /// We didn't calculate whether the designated initializers should be @@ -1463,7 +1701,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl } ObjCPropertyDecl - *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; + *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const; void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const override; @@ -1529,8 +1768,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// including in all categories except for category passed /// as argument. ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, - const ObjCCategoryDecl *Cat) const { - return lookupMethod(Sel, true/*isInstance*/, + const ObjCCategoryDecl *Cat, + bool IsClassProperty) const { + return lookupMethod(Sel, !IsClassProperty/*isInstance*/, false/*shallowCategoryLookup*/, true /* followsSuper */, Cat); @@ -2099,7 +2339,8 @@ class ObjCImplDecl : public ObjCContainerDecl { void addPropertyImplementation(ObjCPropertyImplDecl *property); - ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; + ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId, + ObjCPropertyQueryKind queryKind) const; ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; // Iterator access to properties. @@ -2407,197 +2648,6 @@ class ObjCCompatibleAliasDecl : public NamedDecl { }; -/// \brief Represents one property declaration in an Objective-C interface. -/// -/// For example: -/// \code{.mm} -/// \@property (assign, readwrite) int MyProperty; -/// \endcode -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 - // Adding a property should change NumPropertyAttrsBits - }; - - enum { - /// \brief Number of bits fitting all the property attributes. - NumPropertyAttrsBits = 14 - }; - - enum SetterKind { Assign, Retain, Copy, Weak }; - enum PropertyControl { None, Required, Optional }; -private: - SourceLocation AtLoc; // location of \@property - SourceLocation LParenLoc; // location of '(' starting attribute list or null. - QualType DeclType; - TypeSourceInfo *DeclTypeSourceInfo; - unsigned PropertyAttributes : NumPropertyAttrsBits; - unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; - // \@required/\@optional - unsigned PropertyImplementation : 2; - - Selector GetterName; // getter name of NULL if no getter - Selector SetterName; // setter name of NULL if no setter - - ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method - ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method - ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property - - 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()), - GetterMethodDecl(nullptr), SetterMethodDecl(nullptr), - PropertyIvarDecl(nullptr) {} - -public: - static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, SourceLocation AtLocation, - SourceLocation LParenLocation, - QualType T, - TypeSourceInfo *TSI, - PropertyControl propControl = None); - - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - SourceLocation getAtLoc() const { return AtLoc; } - void setAtLoc(SourceLocation L) { AtLoc = L; } - - SourceLocation getLParenLoc() const { return LParenLoc; } - void setLParenLoc(SourceLocation L) { LParenLoc = L; } - - TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; } - - QualType getType() const { return DeclType; } - - void setType(QualType T, TypeSourceInfo *TSI) { - DeclType = T; - DeclTypeSourceInfo = TSI; - } - - /// Retrieve the type when this property is used with a specific base object - /// type. - QualType getUsageType(QualType objectType) const; - - PropertyAttributeKind getPropertyAttributes() const { - return PropertyAttributeKind(PropertyAttributes); - } - void setPropertyAttributes(PropertyAttributeKind PRVal) { - PropertyAttributes |= PRVal; - } - void overwritePropertyAttributes(unsigned PRVal) { - PropertyAttributes = PRVal; - } - - PropertyAttributeKind getPropertyAttributesAsWritten() const { - return PropertyAttributeKind(PropertyAttributesAsWritten); - } - - void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { - PropertyAttributesAsWritten = PRVal; - } - - // Helper methods for accessing attributes. - - /// isReadOnly - Return true iff the property has a setter. - bool isReadOnly() const { - return (PropertyAttributes & OBJC_PR_readonly); - } - - /// isAtomic - Return true if the property is atomic. - bool isAtomic() const { - return (PropertyAttributes & OBJC_PR_atomic); - } - - /// isRetaining - Return true if the property retains its value. - bool isRetaining() const { - return (PropertyAttributes & - (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); - } - - /// getSetterKind - Return the method used for doing assignment in - /// 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) - return getType()->isBlockPointerType() ? Copy : Retain; - if (PropertyAttributes & OBJC_PR_retain) - return Retain; - if (PropertyAttributes & OBJC_PR_copy) - return Copy; - if (PropertyAttributes & OBJC_PR_weak) - return Weak; - return Assign; - } - - Selector getGetterName() const { return GetterName; } - void setGetterName(Selector Sel) { GetterName = Sel; } - - Selector getSetterName() const { return SetterName; } - void setSetterName(Selector Sel) { SetterName = Sel; } - - ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } - void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } - - ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } - void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } - - // Related to \@optional/\@required declared in \@protocol - void setPropertyImplementation(PropertyControl pc) { - PropertyImplementation = pc; - } - PropertyControl getPropertyImplementation() const { - return PropertyControl(PropertyImplementation); - } - - void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { - PropertyIvarDecl = Ivar; - } - ObjCIvarDecl *getPropertyIvarDecl() const { - return PropertyIvarDecl; - } - - SourceRange getSourceRange() const override LLVM_READONLY { - return SourceRange(AtLoc, getLocation()); - } - - /// Get the default name of the synthesized ivar. - IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; - - /// Lookup a property by name in the specified DeclContext. - static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, - const IdentifierInfo *propertyID); - - static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classofKind(Kind K) { return K == ObjCProperty; } -}; - /// ObjCPropertyImplDecl - Represents implementation declaration of a property /// in a class or category implementation block. For example: /// \@synthesize prop1 = ivar1; diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h index 598f418f7e3..1975bc551ca 100644 --- a/include/clang/AST/DeclOpenMP.h +++ b/include/clang/AST/DeclOpenMP.h @@ -15,11 +15,14 @@ #ifndef LLVM_CLANG_AST_DECLOPENMP_H #define LLVM_CLANG_AST_DECLOPENMP_H -#include "clang/AST/DeclBase.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Type.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/TrailingObjects.h" namespace clang { -class Expr; /// \brief This represents '#pragma omp threadprivate ...' directive. /// For example, in the following, both 'a' and 'A::b' are threadprivate: @@ -86,6 +89,107 @@ class OMPThreadPrivateDecl final static bool classofKind(Kind K) { return K == OMPThreadPrivate; } }; -} // end namespace clang +/// \brief This represents '#pragma omp declare reduction ...' directive. +/// For example, in the following, declared reduction 'foo' for types 'int' and +/// 'float': +/// +/// \code +/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \ +/// initializer (omp_priv = 0) +/// \endcode +/// +/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer. +class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext { +private: + friend class ASTDeclReader; + /// \brief Combiner for declare reduction construct. + Expr *Combiner; + /// \brief Initializer for declare reduction construct. + Expr *Initializer; + /// \brief Reference to the previous declare reduction construct in the same + /// scope with the same name. Required for proper templates instantiation if + /// the declare reduction construct is declared inside compound statement. + LazyDeclPtr PrevDeclInScope; + + virtual void anchor(); + + OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, QualType Ty, + OMPDeclareReductionDecl *PrevDeclInScope) + : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr), + Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {} + + void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) { + PrevDeclInScope = Prev; + } + +public: + /// \brief Create declare reduction node. + static OMPDeclareReductionDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, + QualType T, OMPDeclareReductionDecl *PrevDeclInScope); + /// \brief Create deserialized declare reduction node. + static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + /// \brief Get combiner expression of the declare reduction construct. + Expr *getCombiner() { return Combiner; } + const Expr *getCombiner() const { return Combiner; } + /// \brief Set combiner expression for the declare reduction construct. + void setCombiner(Expr *E) { Combiner = E; } + + /// \brief Get initializer expression (if specified) of the declare reduction + /// construct. + Expr *getInitializer() { return Initializer; } + const Expr *getInitializer() const { return Initializer; } + /// \brief Set initializer expression for the declare reduction construct. + void setInitializer(Expr *E) { Initializer = E; } + + /// \brief Get reference to previous declare reduction construct in the same + /// scope with the same name. + OMPDeclareReductionDecl *getPrevDeclInScope(); + const OMPDeclareReductionDecl *getPrevDeclInScope() const; + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPDeclareReduction; } + static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) { + return static_cast(const_cast(D)); + } + static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast( + const_cast(DC)); + } +}; + +/// Pseudo declaration for capturing expressions. Also is used for capturing of +/// non-static data members in non-static member functions. +/// +/// Clang supports capturing of variables only, but OpenMP 4.5 allows to +/// privatize non-static members of current class in non-static member +/// functions. This pseudo-declaration allows properly handle this kind of +/// capture by wrapping captured expression into a variable-like declaration. +class OMPCapturedExprDecl final : public VarDecl { + friend class ASTDeclReader; + void anchor() override; + + OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, + QualType Type) + : VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id, + Type, nullptr, SC_None) { + setImplicit(); + } + +public: + static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id, QualType T); + + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPCapturedExpr; } +}; + +} // end namespace clang #endif diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index a9109ef1142..4ac8cdc9bee 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -22,6 +22,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" #include +#include namespace clang { @@ -183,7 +184,7 @@ class TemplateArgumentList final // Constructs an instance with an internal Argument list, containing // a copy of the Args array. (Called by CreateCopy) - TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs); + TemplateArgumentList(ArrayRef Args); public: /// \brief Type used to indicate that the template argument list itself is a @@ -193,16 +194,14 @@ class TemplateArgumentList final /// \brief Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, - const TemplateArgument *Args, - unsigned NumArgs); + ArrayRef Args); /// \brief Construct a new, temporary template argument list on the stack. /// /// The template argument list does not own the template arguments /// provided. - explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args, - unsigned NumArgs) - : Arguments(Args), NumArguments(NumArgs) {} + explicit TemplateArgumentList(OnStackType, ArrayRef Args) + : Arguments(Args.data()), NumArguments(Args.size()) {} /// \brief Produces a shallow copy of the given template argument list. /// @@ -332,24 +331,23 @@ class TemplateDecl : public NamedDecl { void anchor() override; protected: // This is probably never used. - TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr), - TemplateParams(nullptr) {} + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false), + TemplateParams(nullptr) {} // Construct a template decl with the given name and parameters. // Used when there is not templated element (tt-params). - TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name, TemplateParameterList *Params) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr), - TemplateParams(Params) {} + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false), + TemplateParams(Params) {} // Construct a template decl with name, parameters, and templated element. - TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name, TemplateParameterList *Params, - NamedDecl *Decl) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), - TemplateParams(Params) { } + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false), + TemplateParams(Params) {} + public: /// Get the list of template parameters TemplateParameterList *getTemplateParameters() const { @@ -357,7 +355,7 @@ class TemplateDecl : public NamedDecl { } /// Get the underlying, templated declaration. - NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } + NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -367,20 +365,30 @@ class TemplateDecl : public NamedDecl { SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(TemplateParams->getTemplateLoc(), - TemplatedDecl->getSourceRange().getEnd()); + TemplatedDecl.getPointer()->getSourceRange().getEnd()); } + /// Whether this is a (C++ Concepts TS) function or variable concept. + bool isConcept() const { return TemplatedDecl.getInt(); } + void setConcept() { TemplatedDecl.setInt(true); } + protected: - NamedDecl *TemplatedDecl; + /// \brief The named declaration from which this template was instantiated. + /// (or null). + /// + /// The boolean value will be true to indicate that this template + /// (function or variable) is a concept. + llvm::PointerIntPair TemplatedDecl; + TemplateParameterList* TemplateParams; public: /// \brief Initialize the underlying templated declaration and /// template parameters. void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { - assert(!TemplatedDecl && "TemplatedDecl already set!"); + assert(!TemplatedDecl.getPointer() && "TemplatedDecl already set!"); assert(!TemplateParams && "TemplateParams already set!"); - TemplatedDecl = templatedDecl; + TemplatedDecl.setPointer(templatedDecl); TemplateParams = templateParams; } }; @@ -481,8 +489,8 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { Profile(llvm::FoldingSetNodeID &ID, ArrayRef TemplateArgs, ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); - for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg) - TemplateArgs[Arg].Profile(ID, Context); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); } }; @@ -889,7 +897,7 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl { /// Get the underlying function declaration of the template. FunctionDecl *getTemplatedDecl() const { - return static_cast(TemplatedDecl); + return static_cast(TemplatedDecl.getPointer()); } /// Returns whether this template declaration defines the primary @@ -1171,9 +1179,8 @@ class NonTypeTemplateParmDecl final SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - const QualType *ExpandedTypes, - unsigned NumExpandedTypes, - TypeSourceInfo **ExpandedTInfos); + ArrayRef ExpandedTypes, + ArrayRef ExpandedTInfos); friend class ASTDeclReader; friend TrailingObjects; @@ -1187,9 +1194,8 @@ class NonTypeTemplateParmDecl final static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - const QualType *ExpandedTypes, unsigned NumExpandedTypes, - TypeSourceInfo **ExpandedTInfos); + QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, + ArrayRef ExpandedTInfos); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1352,8 +1358,7 @@ class TemplateTemplateParmDecl final TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, TemplateParameterList *Params, - unsigned NumExpansions, - TemplateParameterList * const *Expansions); + ArrayRef Expansions); public: static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, @@ -1480,8 +1485,8 @@ class TemplateTemplateParmDecl final }; /// \brief Represents the builtin template declaration which is used to -/// implement __make_integer_seq. It serves no real purpose beyond existing as -/// a place to hold template parameters. +/// implement __make_integer_seq and other builtin templates. It serves +/// no real purpose beyond existing as a place to hold template parameters. class BuiltinTemplateDecl : public TemplateDecl { void anchor() override; @@ -1573,8 +1578,7 @@ class ClassTemplateSpecializationDecl DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK); @@ -1584,8 +1588,7 @@ class ClassTemplateSpecializationDecl Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID); @@ -1762,8 +1765,8 @@ class ClassTemplateSpecializationDecl Profile(llvm::FoldingSetNodeID &ID, ArrayRef TemplateArgs, ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); - for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg) - TemplateArgs[Arg].Profile(ID, Context); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1801,8 +1804,7 @@ class ClassTemplatePartialSpecializationDecl SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, const ASTTemplateArgumentListInfo *ArgsAsWritten, ClassTemplatePartialSpecializationDecl *PrevDecl); @@ -1817,8 +1819,7 @@ class ClassTemplatePartialSpecializationDecl SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl); @@ -1867,6 +1868,10 @@ class ClassTemplatePartialSpecializationDecl cast(getFirstDecl()); return First->InstantiatedFromMember.getPointer(); } + ClassTemplatePartialSpecializationDecl * + getInstantiatedFromMemberTemplate() const { + return getInstantiatedFromMember(); + } void setInstantiatedFromMember( ClassTemplatePartialSpecializationDecl *PartialSpec) { @@ -1982,7 +1987,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { /// \brief Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { - return static_cast(TemplatedDecl); + return static_cast(TemplatedDecl.getPointer()); } /// \brief Returns whether this template declaration defines the primary @@ -2154,18 +2159,11 @@ class FriendTemplateDecl : public Decl { // Location of the 'friend' specifier. SourceLocation FriendLoc; - FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, - unsigned NParams, - TemplateParameterList **Params, - FriendUnion Friend, - SourceLocation FriendLoc) - : Decl(Decl::FriendTemplate, DC, Loc), - NumParams(NParams), - Params(Params), - Friend(Friend), - FriendLoc(FriendLoc) - {} + MutableArrayRef Params, + FriendUnion Friend, SourceLocation FriendLoc) + : Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()), + Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {} FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty), @@ -2174,12 +2172,10 @@ class FriendTemplateDecl : public Decl { {} public: - static FriendTemplateDecl *Create(ASTContext &Context, - DeclContext *DC, SourceLocation Loc, - unsigned NParams, - TemplateParameterList **Params, - FriendUnion Friend, - SourceLocation FriendLoc); + static FriendTemplateDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, + MutableArrayRef Params, FriendUnion Friend, + SourceLocation FriendLoc); static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2245,7 +2241,7 @@ class TypeAliasTemplateDecl : public RedeclarableTemplateDecl { public: /// Get the underlying function declaration of the template. TypeAliasDecl *getTemplatedDecl() const { - return static_cast(TemplatedDecl); + return static_cast(TemplatedDecl.getPointer()); } @@ -2319,9 +2315,9 @@ class ClassScopeFunctionSpecializationDecl : public Decl { ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, bool Args, TemplateArgumentListInfo TemplArgs) - : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), - Specialization(FD), HasExplicitTemplateArgs(Args), - TemplateArgs(TemplArgs) {} + : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), + Specialization(FD), HasExplicitTemplateArgs(Args), + TemplateArgs(std::move(TemplArgs)) {} ClassScopeFunctionSpecializationDecl(EmptyShell Empty) : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} @@ -2342,7 +2338,7 @@ class ClassScopeFunctionSpecializationDecl : public Decl { bool HasExplicitTemplateArgs, TemplateArgumentListInfo TemplateArgs) { return new (C, DC) ClassScopeFunctionSpecializationDecl( - DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs); + DC, Loc, FD, HasExplicitTemplateArgs, std::move(TemplateArgs)); } static ClassScopeFunctionSpecializationDecl * @@ -2428,8 +2424,8 @@ class VarTemplateSpecializationDecl : public VarDecl, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, const TemplateArgument *Args, - unsigned NumArgs); + StorageClass S, + ArrayRef Args); explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context); @@ -2437,8 +2433,8 @@ class VarTemplateSpecializationDecl : public VarDecl, static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, - unsigned NumArgs); + TypeSourceInfo *TInfo, StorageClass S, + ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2502,17 +2498,11 @@ class VarTemplateSpecializationDecl : public VarDecl, /// it was instantiated. llvm::PointerUnion getInstantiatedFrom() const { - if (getSpecializationKind() != TSK_ImplicitInstantiation && - getSpecializationKind() != TSK_ExplicitInstantiationDefinition && - getSpecializationKind() != TSK_ExplicitInstantiationDeclaration) + if (!isTemplateInstantiation(getSpecializationKind())) return llvm::PointerUnion(); - if (SpecializedPartialSpecialization *PartialSpec = - SpecializedTemplate.dyn_cast()) - return PartialSpec->PartialSpecialization; - - return SpecializedTemplate.get(); + return getSpecializedTemplateOrPartial(); } /// \brief Retrieve the variable template or variable template partial @@ -2610,8 +2600,8 @@ class VarTemplateSpecializationDecl : public VarDecl, ArrayRef TemplateArgs, ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); - for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg) - TemplateArgs[Arg].Profile(ID, Context); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2647,7 +2637,7 @@ class VarTemplatePartialSpecializationDecl ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, const TemplateArgument *Args, unsigned NumArgs, + StorageClass S, ArrayRef Args, const ASTTemplateArgumentListInfo *ArgInfos); VarTemplatePartialSpecializationDecl(ASTContext &Context) @@ -2660,8 +2650,8 @@ class VarTemplatePartialSpecializationDecl Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, - unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos); + TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args, + const TemplateArgumentListInfo &ArgInfos); static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2808,7 +2798,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { /// \brief Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { - return static_cast(TemplatedDecl); + return static_cast(TemplatedDecl.getPointer()); } /// \brief Returns whether this template declaration defines the primary diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 9482e83e81d..2d3cfe27a16 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -30,6 +30,7 @@ namespace clang { class IdentifierInfo; class MultiKeywordSelector; enum OverloadedOperatorKind : int; + struct PrintingPolicy; class QualType; class Type; class TypeSourceInfo; @@ -302,7 +303,9 @@ class DeclarationName { } static int compare(DeclarationName LHS, DeclarationName RHS); - + + void print(raw_ostream &OS, const PrintingPolicy &Policy); + void dump() const; }; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 38733eee82c..9179c7736a9 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -29,6 +29,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -593,6 +594,13 @@ class Expr : public Stmt { bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + /// EvaluateAsFloat - Return true if this is a constant which we can fold and + /// convert to a floating point value, using any crazy technique that we + /// want to. + bool + EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be /// constant folded without side-effects, but discard the result. bool isEvaluatable(const ASTContext &Ctx, @@ -847,10 +855,12 @@ class OpaqueValueExpr : public Expr { ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr) : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType(), + T->isDependentType() || + (SourceExpr && SourceExpr->isTypeDependent()), T->isDependentType() || (SourceExpr && SourceExpr->isValueDependent()), - T->isInstantiationDependentType(), + T->isInstantiationDependentType() || + (SourceExpr && SourceExpr->isInstantiationDependent()), false), SourceExpr(SourceExpr), Loc(Loc) { } @@ -1110,6 +1120,10 @@ class DeclRefExpr final return getTrailingObjects()->NumTemplateArgs; } + ArrayRef template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// \brief Returns true if this expression refers to a function that /// was resolved from an overloaded set having size greater than 1. bool hadMultipleCandidates() const { @@ -2137,11 +2151,15 @@ class CallExpr : public Expr { unsigned NumArgs; SourceLocation RParenLoc; + void updateDependenciesFromArg(Expr *Arg); + protected: // These versions of the constructor are for derived classes. - CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, - ArrayRef args, QualType t, ExprValueKind VK, - SourceLocation rparenloc); + CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef preargs, ArrayRef args, QualType t, + ExprValueKind VK, SourceLocation rparenloc); + CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef args, + QualType t, ExprValueKind VK, SourceLocation rparenloc); CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); @@ -2477,6 +2495,10 @@ class MemberExpr final return getTrailingObjects()->NumTemplateArgs; } + ArrayRef template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// \brief Retrieve the member declaration name info. DeclarationNameInfo getMemberNameInfo() const { return DeclarationNameInfo(MemberDecl->getDeclName(), @@ -3942,7 +3964,7 @@ class DesignatedInitExpr final /// Whether this designated initializer used the GNU deprecated /// syntax rather than the C99 '=' syntax. - bool GNUSyntax : 1; + unsigned GNUSyntax : 1; /// The number of designators in this initializer expression. unsigned NumDesignators : 15; @@ -3956,11 +3978,10 @@ class DesignatedInitExpr final /// expression. Designator *Designators; - - DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators, - const Designator *Designators, + DesignatedInitExpr(const ASTContext &C, QualType Ty, + llvm::ArrayRef Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, - ArrayRef IndexExprs, Expr *Init); + ArrayRef IndexExprs, Expr *Init); explicit DesignatedInitExpr(unsigned NumSubExprs) : Expr(DesignatedInitExprClass, EmptyShell()), @@ -4120,8 +4141,7 @@ class DesignatedInitExpr final }; static DesignatedInitExpr *Create(const ASTContext &C, - Designator *Designators, - unsigned NumDesignators, + llvm::ArrayRef Designators, ArrayRef IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); @@ -4133,48 +4153,15 @@ class DesignatedInitExpr final unsigned size() const { return NumDesignators; } // Iterator access to the designators. - typedef Designator *designators_iterator; - designators_iterator designators_begin() { return Designators; } - designators_iterator designators_end() { - return Designators + NumDesignators; - } - - typedef const Designator *const_designators_iterator; - const_designators_iterator designators_begin() const { return Designators; } - const_designators_iterator designators_end() const { - return Designators + NumDesignators; - } - - typedef llvm::iterator_range designators_range; - designators_range designators() { - return designators_range(designators_begin(), designators_end()); - } - - typedef llvm::iterator_range - designators_const_range; - designators_const_range designators() const { - return designators_const_range(designators_begin(), designators_end()); + llvm::MutableArrayRef designators() { + return {Designators, NumDesignators}; } - typedef std::reverse_iterator - reverse_designators_iterator; - reverse_designators_iterator designators_rbegin() { - return reverse_designators_iterator(designators_end()); - } - reverse_designators_iterator designators_rend() { - return reverse_designators_iterator(designators_begin()); + llvm::ArrayRef designators() const { + return {Designators, NumDesignators}; } - typedef std::reverse_iterator - const_reverse_designators_iterator; - const_reverse_designators_iterator designators_rbegin() const { - return const_reverse_designators_iterator(designators_end()); - } - const_reverse_designators_iterator designators_rend() const { - return const_reverse_designators_iterator(designators_begin()); - } - - Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } + Designator *getDesignator(unsigned Idx) { return &designators()[Idx]; } void setDesignators(const ASTContext &C, const Designator *Desigs, unsigned NumDesigs); @@ -4824,16 +4811,6 @@ class AtomicExpr : public Expr { BI_First = 0 }; - // The ABI values for various atomic memory orderings. - enum AtomicOrderingKind { - AO_ABI_memory_order_relaxed = 0, - AO_ABI_memory_order_consume = 1, - AO_ABI_memory_order_acquire = 2, - AO_ABI_memory_order_release = 3, - AO_ABI_memory_order_acq_rel = 4, - AO_ABI_memory_order_seq_cst = 5 - }; - private: enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR }; Stmt* SubExprs[END_EXPR]; @@ -4882,9 +4859,12 @@ class AtomicExpr : public Expr { } AtomicOp getOp() const { return Op; } - unsigned getNumSubExprs() { return NumSubExprs; } + unsigned getNumSubExprs() const { return NumSubExprs; } Expr **getSubExprs() { return reinterpret_cast(SubExprs); } + const Expr * const *getSubExprs() const { + return reinterpret_cast(SubExprs); + } bool isVolatile() const { return getPtr()->getType()->getPointeeType().isVolatileQualified(); diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 68212749864..86cbfb2cd0b 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_EXPRCXX_H #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/LambdaCapture.h" #include "clang/AST/TemplateBase.h" @@ -26,9 +27,6 @@ namespace clang { -class CXXConstructorDecl; -class CXXDestructorDecl; -class CXXMethodDecl; class CXXTemporary; class MSPropertyDecl; class TemplateArgumentListInfo; @@ -66,8 +64,7 @@ class CXXOperatorCallExpr : public CallExpr { CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation operatorloc, bool fpContractable) - : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK, - operatorloc), + : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc), Operator(Op), FPContractable(fpContractable) { Range = getSourceRangeImpl(); } @@ -125,7 +122,7 @@ class CXXMemberCallExpr : public CallExpr { public: CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {} + : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } @@ -146,6 +143,14 @@ class CXXMemberCallExpr : public CallExpr { /// FIXME: Returns 0 for member pointer call exprs. CXXRecordDecl *getRecordDecl() const; + SourceLocation getExprLoc() const LLVM_READONLY { + SourceLocation CLoc = getCallee()->getExprLoc(); + if (CLoc.isValid()) + return CLoc; + + return getLocStart(); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXMemberCallExprClass; } @@ -160,9 +165,7 @@ class CUDAKernelCallExpr : public CallExpr { CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) { - setConfig(Config); - } + : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {} CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { } @@ -171,7 +174,20 @@ class CUDAKernelCallExpr : public CallExpr { return cast_or_null(getPreArg(CONFIG)); } CallExpr *getConfig() { return cast_or_null(getPreArg(CONFIG)); } - void setConfig(CallExpr *E) { setPreArg(CONFIG, E); } + + /// \brief Sets the kernel configuration expression. + /// + /// Note that this method cannot be called if config has already been set to a + /// non-null value. + void setConfig(CallExpr *E) { + assert(!getConfig() && + "Cannot call setConfig if config is not null"); + setPreArg(CONFIG, E); + setInstantiationDependent(isInstantiationDependent() || + E->isInstantiationDependent()); + setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() || + E->containsUnexpandedParameterPack()); + } static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; @@ -398,7 +414,7 @@ class UserDefinedLiteral : public CallExpr { UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) - : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), + : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc), UDSuffixLoc(SuffixLoc) {} explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} @@ -768,22 +784,23 @@ class MSPropertySubscriptExpr : public Expr { class CXXUuidofExpr : public Expr { private: llvm::PointerUnion Operand; + StringRef UuidStr; SourceRange Range; public: - CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, - false, Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) { } - - CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, - false, Operand->isTypeDependent(), - Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) { } + CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr, + 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) {} CXXUuidofExpr(EmptyShell Empty, bool isExpr) : Expr(CXXUuidofExprClass, Empty) { @@ -820,7 +837,8 @@ class CXXUuidofExpr : public Expr { Operand = E; } - StringRef getUuidAsStringRef(ASTContext &Context) const; + void setUuidStr(StringRef US) { UuidStr = US; } + StringRef getUuidStr() const { return UuidStr; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -831,11 +849,6 @@ class CXXUuidofExpr : public Expr { return T->getStmtClass() == CXXUuidofExprClass; } - /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to - /// a single GUID. - static const UuidAttr *GetUuidAttrOfType(QualType QT, - bool *HasMultipleGUIDsPtr = nullptr); - // Iterators child_range children() { if (isTypeOperand()) @@ -1161,18 +1174,21 @@ class CXXConstructExpr : public Expr { SourceLocation Loc; SourceRange ParenOrBraceRange; unsigned NumArgs : 16; - bool Elidable : 1; - bool HadMultipleCandidates : 1; - bool ListInitialization : 1; - bool StdInitListInitialization : 1; - bool ZeroInitialization : 1; + unsigned Elidable : 1; + unsigned HadMultipleCandidates : 1; + unsigned ListInitialization : 1; + unsigned StdInitListInitialization : 1; + unsigned ZeroInitialization : 1; unsigned ConstructKind : 2; Stmt **Args; + void setConstructor(CXXConstructorDecl *C) { Constructor = C; } + protected: CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, - CXXConstructorDecl *d, bool elidable, + CXXConstructorDecl *Ctor, + bool Elidable, ArrayRef Args, bool HadMultipleCandidates, bool ListInitialization, @@ -1191,15 +1207,12 @@ class CXXConstructExpr : public Expr { public: /// \brief Construct an empty C++ construction expression. explicit CXXConstructExpr(EmptyShell Empty) - : Expr(CXXConstructExprClass, Empty), Constructor(nullptr), - NumArgs(0), Elidable(false), HadMultipleCandidates(false), - ListInitialization(false), ZeroInitialization(false), - ConstructKind(0), Args(nullptr) - { } + : CXXConstructExpr(CXXConstructExprClass, Empty) {} static CXXConstructExpr *Create(const ASTContext &C, QualType T, SourceLocation Loc, - CXXConstructorDecl *D, bool Elidable, + CXXConstructorDecl *Ctor, + bool Elidable, ArrayRef Args, bool HadMultipleCandidates, bool ListInitialization, @@ -1208,8 +1221,8 @@ class CXXConstructExpr : public Expr { ConstructionKind ConstructKind, SourceRange ParenOrBraceRange); + /// \brief Get the constructor that this expression will (ultimately) call. CXXConstructorDecl *getConstructor() const { return Constructor; } - void setConstructor(CXXConstructorDecl *C) { Constructor = C; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation Loc) { this->Loc = Loc; } @@ -1305,6 +1318,73 @@ class CXXConstructExpr : public Expr { friend class ASTStmtReader; }; +/// \brief Represents a call to an inherited base class constructor from an +/// inheriting constructor. This call implicitly forwards the arguments from +/// the enclosing context (an inheriting constructor) to the specified inherited +/// base class constructor. +class CXXInheritedCtorInitExpr : public Expr { +private: + CXXConstructorDecl *Constructor; + + /// The location of the using declaration. + SourceLocation Loc; + + /// Whether this is the construction of a virtual base. + unsigned ConstructsVirtualBase : 1; + + /// Whether the constructor is inherited from a virtual base class of the + /// class that we construct. + unsigned InheritedFromVirtualBase : 1; + +public: + /// \brief Construct a C++ inheriting construction expression. + CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, + CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, + bool InheritedFromVirtualBase) + : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false, + false, false, false), + Constructor(Ctor), Loc(Loc), + ConstructsVirtualBase(ConstructsVirtualBase), + InheritedFromVirtualBase(InheritedFromVirtualBase) { + assert(!T->isDependentType()); + } + + /// \brief Construct an empty C++ inheriting construction expression. + explicit CXXInheritedCtorInitExpr(EmptyShell Empty) + : Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr), + ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {} + + /// \brief Get the constructor that this expression will call. + CXXConstructorDecl *getConstructor() const { return Constructor; } + + /// \brief Determine whether this constructor is actually constructing + /// a base class (rather than a complete object). + bool constructsVBase() const { return ConstructsVirtualBase; } + CXXConstructExpr::ConstructionKind getConstructionKind() const { + return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase + : CXXConstructExpr::CK_NonVirtualBase; + } + + /// \brief Determine whether the inherited constructor is inherited from a + /// virtual base of the object we construct. If so, we are not responsible + /// for calling the inherited constructor (the complete object constructor + /// does that), and so we don't need to pass any arguments. + bool inheritedFromVBase() const { return InheritedFromVirtualBase; } + + SourceLocation getLocation() const LLVM_READONLY { return Loc; } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXInheritedCtorInitExprClass; + } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + friend class ASTStmtReader; +}; + /// \brief Represents an explicit C++ type conversion that uses "functional" /// notation (C++ [expr.type.conv]). /// @@ -1375,7 +1455,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr { TypeSourceInfo *Type; public: - CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, + CXXTemporaryObjectExpr(const ASTContext &C, + CXXConstructorDecl *Cons, TypeSourceInfo *Type, ArrayRef Args, SourceRange ParenOrBraceRange, @@ -1744,12 +1825,12 @@ class CXXNewExpr : public Expr { SourceRange DirectInitRange; /// Was the usage ::new, i.e. is the global new to be used? - bool GlobalNew : 1; + unsigned GlobalNew : 1; /// Do we allocate an array? If so, the first SubExpr is the size expression. - bool Array : 1; + unsigned Array : 1; /// If this is an array allocation, does the usual deallocation /// function for the allocated type want to know the allocated size? - bool UsualArrayDeleteWantsSize : 1; + unsigned UsualArrayDeleteWantsSize : 1; /// The number of placement new arguments. unsigned NumPlacementArgs : 13; /// What kind of initializer do we have? Could be none, parens, or braces. @@ -2348,7 +2429,7 @@ class ExpressionTraitExpr : public Expr { /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned. unsigned ET : 31; /// \brief The value of the type trait. Unspecified if dependent. - bool Value : 1; + unsigned Value : 1; /// \brief The location of the type trait keyword. SourceLocation Loc; @@ -2557,6 +2638,10 @@ class OverloadExpr : public Expr { return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; } + ArrayRef template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// \brief Copies the template arguments into the given structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) @@ -2810,6 +2895,10 @@ class DependentScopeDeclRefExpr final return getTrailingObjects()->NumTemplateArgs; } + ArrayRef template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, /// and differs from getLocation().getStart(). SourceLocation getLocStart() const LLVM_READONLY { @@ -2858,7 +2947,8 @@ class ExprWithCleanups final Stmt *SubExpr; ExprWithCleanups(EmptyShell, unsigned NumObjects); - ExprWithCleanups(Expr *SubExpr, ArrayRef Objects); + ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects, + ArrayRef Objects); friend TrailingObjects; friend class ASTStmtReader; @@ -2868,6 +2958,7 @@ class ExprWithCleanups final unsigned numObjects); static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, + bool CleanupsHaveSideEffects, ArrayRef objects); ArrayRef getObjects() const { @@ -2884,6 +2975,9 @@ class ExprWithCleanups final Expr *getSubExpr() { return cast(SubExpr); } const Expr *getSubExpr() const { return cast(SubExpr); } + bool cleanupsHaveSideEffects() const { + return ExprWithCleanupsBits.CleanupsHaveSideEffects; + } /// As with any mutator of the AST, be very careful /// when modifying an existing AST to preserve its invariants. @@ -3220,6 +3314,10 @@ class CXXDependentScopeMemberExpr final return getTrailingObjects()->NumTemplateArgs; } + ArrayRef template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + SourceLocation getLocStart() const LLVM_READONLY { if (!isImplicitAccess()) return Base->getLocStart(); diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 61e6383bffe..5f9623db241 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -1562,7 +1562,52 @@ class ObjCBridgedCastExpr final return T->getStmtClass() == ObjCBridgedCastExprClass; } }; - + +/// \brief A runtime availability query. +/// +/// There are 2 ways to spell this node: +/// \code +/// @available(macos 10.10, ios 8, *); // Objective-C +/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C +/// \endcode +/// +/// Note that we only need to keep track of one \c VersionTuple here, which is +/// the one that corresponds to the current deployment target. This is meant to +/// be used in the condition of an \c if, but it is also usable as top level +/// expressions. +/// +class ObjCAvailabilityCheckExpr : public Expr { + VersionTuple VersionToCheck; + SourceLocation AtLoc, RParen; + + friend class ASTStmtReader; +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) {} + + explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) + : Expr(ObjCAvailabilityCheckExprClass, Shell) {} + + SourceLocation getLocStart() const { return AtLoc; } + SourceLocation getLocEnd() const { return RParen; } + SourceRange getSourceRange() const { return {AtLoc, RParen}; } + + /// \brief This may be '*', in which case this should fold to true. + bool hasVersion() const { return !VersionToCheck.empty(); } + VersionTuple getVersion() { return VersionToCheck; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCAvailabilityCheckExprClass; + } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h index 2d71a3ad47c..a4ef93ba8b1 100644 --- a/include/clang/AST/ExprOpenMP.h +++ b/include/clang/AST/ExprOpenMP.h @@ -85,7 +85,7 @@ class OMPArraySectionExpr : public Expr { void setBase(Expr *E) { SubExprs[BASE] = E; } /// \brief Return original type of the base expression for array section. - static QualType getBaseOriginalType(Expr *Base); + static QualType getBaseOriginalType(const Expr *Base); /// \brief Get lower bound of array section. Expr *getLowerBound() { return cast_or_null(SubExprs[LOWER_BOUND]); } diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h index 54c9d88c9b2..adf63a3aea6 100644 --- a/include/clang/AST/GlobalDecl.h +++ b/include/clang/AST/GlobalDecl.h @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/Basic/ABI.h" namespace clang { @@ -43,6 +44,7 @@ class GlobalDecl { GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } + GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h index ddefa88a6b6..6517d656878 100644 --- a/include/clang/AST/LambdaCapture.h +++ b/include/clang/AST/LambdaCapture.h @@ -33,10 +33,22 @@ class LambdaCapture { /// given capture was by-copy. /// /// This includes the case of a non-reference init-capture. - Capture_ByCopy = 0x02 + Capture_ByCopy = 0x02, + + /// \brief Flag used by the Capture class to distinguish between a capture + /// of '*this' and a capture of a VLA type. + Capture_This = 0x04 }; - llvm::PointerIntPair DeclAndBits; + // Decl could represent: + // - a VarDecl* that represents the variable that was captured or the + // init-capture. + // - or, is a nullptr and Capture_This is set in Bits if this represents a + // capture of '*this' by value or reference. + // - or, is a nullptr and Capture_This is not set in Bits if this represents + // a capture of a VLA type. + llvm::PointerIntPair DeclAndBits; + SourceLocation Loc; SourceLocation EllipsisLoc; @@ -69,8 +81,8 @@ class LambdaCapture { /// \brief Determine whether this capture handles the C++ \c this /// pointer. bool capturesThis() const { - return (DeclAndBits.getPointer() == nullptr) && - !(DeclAndBits.getInt() & Capture_ByCopy); + return DeclAndBits.getPointer() == nullptr && + (DeclAndBits.getInt() & Capture_This); } /// \brief Determine whether this capture handles a variable. @@ -81,8 +93,8 @@ class LambdaCapture { /// \brief Determine whether this captures a variable length array bound /// expression. bool capturesVLAType() const { - return (DeclAndBits.getPointer() == nullptr) && - (DeclAndBits.getInt() & Capture_ByCopy); + return DeclAndBits.getPointer() == nullptr && + !(DeclAndBits.getInt() & Capture_This); } /// \brief Retrieve the declaration of the local variable being @@ -91,13 +103,15 @@ class LambdaCapture { /// This operation is only valid if this capture is a variable capture /// (other than a capture of \c this). VarDecl *getCapturedVar() const { - assert(capturesVariable() && "No variable available for 'this' capture"); - return cast(DeclAndBits.getPointer()); + assert(capturesVariable() && "No variable available for capture"); + return static_cast(DeclAndBits.getPointer()); } /// \brief Determine whether this was an implicit capture (not /// written between the square brackets introducing the lambda). - bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; } + bool isImplicit() const { + return DeclAndBits.getInt() & Capture_Implicit; + } /// \brief Determine whether this was an explicit capture (written /// between the square brackets introducing the lambda). diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/AST/LocInfoType.h similarity index 88% rename from include/clang/Sema/LocInfoType.h rename to include/clang/AST/LocInfoType.h index 63dfa72b8f7..7e573bd7bac 100644 --- a/include/clang/Sema/LocInfoType.h +++ b/include/clang/AST/LocInfoType.h @@ -36,11 +36,10 @@ 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->isDependentType(), + ty->isInstantiationDependentType(), ty->isVariablyModifiedType(), + ty->containsUnexpandedParameterPack()), + DeclInfo(TInfo) { assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); } friend class Sema; diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile deleted file mode 100644 index 85e6449c509..00000000000 --- a/include/clang/AST/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \ - StmtNodes.inc DeclNodes.inc \ - CommentNodes.inc CommentHTMLTags.inc \ - CommentHTMLTagsProperties.inc \ - CommentHTMLNamedCharacterReferences.inc \ - CommentCommandInfo.inc \ - CommentCommandList.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute classes with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute implementations with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute dumper with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute AST visitor with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang statement node tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang declaration node tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang comment node tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang comment HTML tag matchers with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang comment HTML tag properties with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \ - $(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang named character reference translation function with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang comment command info with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang list of comment commands with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $< - diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index 4872738e7a1..6e3ef9da0c3 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_MANGLE_H #define LLVM_CLANG_AST_MANGLE_H +#include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -123,6 +124,7 @@ class MangleContext { void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); + void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &); void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; @@ -206,7 +208,8 @@ class MicrosoftMangleContext : public MangleContext { raw_ostream &Out) = 0; virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, - uint32_t NumEntries, raw_ostream &Out) = 0; + bool IsUnaligned, uint32_t NumEntries, + raw_ostream &Out) = 0; virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out) = 0; diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index 7632a4b3560..43988cd864b 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -70,6 +70,51 @@ class OMPClause { static bool classof(const OMPClause *) { return true; } }; +/// Class that handles pre-initialization statement for some clauses, like +/// 'shedule', 'firstprivate' etc. +class OMPClauseWithPreInit { + friend class OMPClauseReader; + /// Pre-initialization statement for the clause. + Stmt *PreInit; +protected: + /// Set pre-initialization statement for the clause. + void setPreInitStmt(Stmt *S) { PreInit = S; } + OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) { + assert(get(This) && "get is not tuned for pre-init."); + } + +public: + /// Get pre-initialization statement for the clause. + const Stmt *getPreInitStmt() const { return PreInit; } + /// Get pre-initialization statement for the clause. + Stmt *getPreInitStmt() { return PreInit; } + static OMPClauseWithPreInit *get(OMPClause *C); + static const OMPClauseWithPreInit *get(const OMPClause *C); +}; + +/// Class that handles post-update expression for some clauses, like +/// 'lastprivate', 'reduction' etc. +class OMPClauseWithPostUpdate : public OMPClauseWithPreInit { + friend class OMPClauseReader; + /// Post-update expression for the clause. + Expr *PostUpdate; +protected: + /// Set pre-initialization statement for the clause. + void setPostUpdateExpr(Expr *S) { PostUpdate = S; } + OMPClauseWithPostUpdate(const OMPClause *This) + : OMPClauseWithPreInit(This), PostUpdate(nullptr) { + assert(get(This) && "get is not tuned for post-update."); + } + +public: + /// Get post-update expression for the clause. + const Expr *getPostUpdateExpr() const { return PostUpdate; } + /// Get post-update expression for the clause. + Expr *getPostUpdateExpr() { return PostUpdate; } + static OMPClauseWithPostUpdate *get(OMPClause *C); + static const OMPClauseWithPostUpdate *get(const OMPClause *C); +}; + /// \brief This represents clauses with the list of variables like 'private', /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the /// '#pragma omp ...' directives. @@ -650,7 +695,7 @@ class OMPProcBindClause : public OMPClause { /// In this example directive '#pragma omp for' has 'schedule' clause with /// arguments 'static' and '3'. /// -class OMPScheduleClause : public OMPClause { +class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -665,10 +710,8 @@ class OMPScheduleClause : public OMPClause { SourceLocation KindLoc; /// \brief Location of ',' (if any). SourceLocation CommaLoc; - /// \brief Chunk size and a reference to pseudo variable for combined - /// directives. - enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS }; - Stmt *ChunkSizes[NUM_EXPRS]; + /// \brief Chunk size. + Expr *ChunkSize; /// \brief Set schedule kind. /// @@ -730,12 +773,7 @@ class OMPScheduleClause : public OMPClause { /// /// \param E Chunk size. /// - void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; } - /// \brief Set helper chunk size. - /// - /// \param E Helper chunk size. - /// - void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; } + void setChunkSize(Expr *E) { ChunkSize = E; } public: /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size @@ -757,13 +795,13 @@ class OMPScheduleClause : public OMPClause { OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, Expr *HelperChunkSize, + Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) { - ChunkSizes[CHUNK_SIZE] = ChunkSize; - ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize; + : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), + ChunkSize(ChunkSize) { + setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; ModifiersLoc[FIRST] = M1Loc; @@ -774,9 +812,8 @@ class OMPScheduleClause : public OMPClause { /// explicit OMPScheduleClause() : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), - Kind(OMPC_SCHEDULE_unknown) { - ChunkSizes[CHUNK_SIZE] = nullptr; - ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; + OMPClauseWithPreInit(this), Kind(OMPC_SCHEDULE_unknown), + ChunkSize(nullptr) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; } @@ -815,29 +852,18 @@ class OMPScheduleClause : public OMPClause { SourceLocation getCommaLoc() { return CommaLoc; } /// \brief Get chunk size. /// - Expr *getChunkSize() { return dyn_cast_or_null(ChunkSizes[CHUNK_SIZE]); } + Expr *getChunkSize() { return ChunkSize; } /// \brief Get chunk size. /// - Expr *getChunkSize() const { - return dyn_cast_or_null(ChunkSizes[CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() { - return dyn_cast_or_null(ChunkSizes[HELPER_CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() const { - return dyn_cast_or_null(ChunkSizes[HELPER_CHUNK_SIZE]); - } + const Expr *getChunkSize() const { return ChunkSize; } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_schedule; } child_range children() { - return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); + return child_range(reinterpret_cast(&ChunkSize), + reinterpret_cast(&ChunkSize) + 1); } }; @@ -1250,6 +1276,7 @@ class OMPPrivateClause final /// class OMPFirstprivateClause final : public OMPVarListClause, + public OMPClauseWithPreInit, private llvm::TrailingObjects { friend TrailingObjects; friend OMPVarListClause; @@ -1265,7 +1292,8 @@ class OMPFirstprivateClause final OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) : OMPVarListClause(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N) {} + LParenLoc, EndLoc, N), + OMPClauseWithPreInit(this) {} /// \brief Build an empty clause. /// @@ -1274,7 +1302,8 @@ class OMPFirstprivateClause final explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause( OMPC_firstprivate, SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + SourceLocation(), N), + OMPClauseWithPreInit(this) {} /// \brief Sets the list of references to private copies with initializers for /// new private variables. /// \param VL List of references. @@ -1315,11 +1344,13 @@ class OMPFirstprivateClause final /// \param InitVL List of references to auto generated variables used for /// initialization of a single array element. Used if firstprivate variable is /// of array type. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. /// static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef VL, ArrayRef PrivateVL, - ArrayRef InitVL); + ArrayRef InitVL, Stmt *PreInit); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1374,6 +1405,7 @@ class OMPFirstprivateClause final /// with the variables 'a' and 'b'. class OMPLastprivateClause final : public OMPVarListClause, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects { // There are 4 additional tail-allocated arrays at the end of the class: // 1. Contains list of pseudo variables with the default initialization for @@ -1406,7 +1438,8 @@ class OMPLastprivateClause final OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) : OMPVarListClause(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N) {} + LParenLoc, EndLoc, N), + OMPClauseWithPostUpdate(this) {} /// \brief Build an empty clause. /// @@ -1415,7 +1448,8 @@ class OMPLastprivateClause final explicit OMPLastprivateClause(unsigned N) : OMPVarListClause( OMPC_lastprivate, SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + SourceLocation(), N), + OMPClauseWithPostUpdate(this) {} /// \brief Get the list of helper expressions for initialization of private /// copies for lastprivate variables. @@ -1488,12 +1522,16 @@ class OMPLastprivateClause final /// \endcode /// Required for proper codegen of final assignment performed by the /// lastprivate clause. - /// + /// \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 OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef VL, ArrayRef SrcExprs, - ArrayRef DstExprs, ArrayRef AssignmentOps); + ArrayRef DstExprs, ArrayRef AssignmentOps, + Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1627,6 +1665,7 @@ class OMPSharedClause final /// class OMPReductionClause final : public OMPVarListClause, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects { friend TrailingObjects; friend OMPVarListClause; @@ -1654,7 +1693,8 @@ class OMPReductionClause final const DeclarationNameInfo &NameInfo) : OMPVarListClause(OMPC_reduction, StartLoc, LParenLoc, EndLoc, N), - ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} + OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), + QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} /// \brief Build an empty clause. /// @@ -1664,7 +1704,7 @@ class OMPReductionClause final : OMPVarListClause(OMPC_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), - ColonLoc(), QualifierLoc(), NameInfo() {} + OMPClauseWithPostUpdate(this), ColonLoc(), QualifierLoc(), NameInfo() {} /// \brief Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -1757,6 +1797,10 @@ class OMPReductionClause final /// \endcode /// Required for proper codegen of final reduction operation performed by the /// reduction clause. + /// \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, @@ -1764,7 +1808,7 @@ class OMPReductionClause final NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef Privates, ArrayRef LHSExprs, ArrayRef RHSExprs, - ArrayRef ReductionOps); + ArrayRef ReductionOps, Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1833,6 +1877,7 @@ class OMPReductionClause final /// class OMPLinearClause final : public OMPVarListClause, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects { friend TrailingObjects; friend OMPVarListClause; @@ -1864,7 +1909,8 @@ class OMPLinearClause final unsigned NumVars) : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, EndLoc, NumVars), - Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} + OMPClauseWithPostUpdate(this), Modifier(Modifier), + ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} /// \brief Build an empty clause. /// @@ -1874,7 +1920,8 @@ class OMPLinearClause final : OMPVarListClause(OMPC_linear, SourceLocation(), SourceLocation(), SourceLocation(), NumVars), - Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {} + OMPClauseWithPostUpdate(this), Modifier(OMPC_LINEAR_val), ModifierLoc(), + ColonLoc() {} /// \brief Gets the list of initial values for linear variables. /// @@ -1943,11 +1990,16 @@ class OMPLinearClause final /// \param IL List of initial values for the variables. /// \param Step Linear step. /// \param CalcStep Calculation of the linear step. + /// \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 OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef VL, - ArrayRef PL, ArrayRef IL, Expr *Step, Expr *CalcStep); + ArrayRef PL, ArrayRef IL, Expr *Step, Expr *CalcStep, + Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a NumVars variables. /// @@ -2577,7 +2629,6 @@ class OMPDependClause final /// \param DepLoc Location of the dependency type. /// \param ColonLoc Colon location. /// \param VL List of references to the variables. - /// static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, @@ -2596,6 +2647,14 @@ class OMPDependClause final /// \brief Get colon location. SourceLocation getColonLoc() const { return ColonLoc; } + /// Set the loop counter value for the depend clauses with 'sink|source' kind + /// of dependency. Required for codegen. + void setCounterValue(Expr *V); + /// Get the loop counter value. + Expr *getCounterValue(); + /// Get the loop counter value. + const Expr *getCounterValue() const; + child_range children() { return child_range(reinterpret_cast(varlist_begin()), reinterpret_cast(varlist_end())); @@ -2722,6 +2781,495 @@ class OMPSIMDClause : public OMPClause { } }; +/// \brief Struct that defines common infrastructure to handle mappable +/// expressions used in OpenMP clauses. +class OMPClauseMappableExprCommon { +public: + // \brief Class that represents a component of a mappable expression. E.g. + // for an expression S.a, the first component is a declaration reference + // expression associated with 'S' and the second is a member expression + // associated with the field declaration 'a'. If the expression is an array + // subscript it may not have any associated declaration. In that case the + // associated declaration is set to nullptr. + class MappableComponent { + // \brief Expression associated with the component. + Expr *AssociatedExpression = nullptr; + // \brief Declaration associated with the declaration. If the component does + // not have a declaration (e.g. array subscripts or section), this is set to + // nullptr. + ValueDecl *AssociatedDeclaration = nullptr; + + public: + explicit MappableComponent() {} + explicit MappableComponent(Expr *AssociatedExpression, + ValueDecl *AssociatedDeclaration) + : AssociatedExpression(AssociatedExpression), + AssociatedDeclaration( + AssociatedDeclaration + ? cast(AssociatedDeclaration->getCanonicalDecl()) + : nullptr) {} + + Expr *getAssociatedExpression() const { return AssociatedExpression; } + ValueDecl *getAssociatedDeclaration() const { + return AssociatedDeclaration; + } + }; + + // \brief List of components of an expression. This first one is the whole + // expression and the last one is the base expression. + typedef SmallVector MappableExprComponentList; + typedef ArrayRef MappableExprComponentListRef; + + // \brief List of all component lists associated to the same base declaration. + // E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have + // their component list but the same base declaration 'S'. + typedef SmallVector MappableExprComponentLists; + typedef ArrayRef MappableExprComponentListsRef; + +protected: + // \brief Return the total number of elements in a list of component lists. + static unsigned + getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists); + + // \brief Return the total number of elements in a list of declarations. All + // declarations are expected to be canonical. + static unsigned + getUniqueDeclarationsTotalNumber(ArrayRef Declarations); +}; + +/// \brief This represents clauses with a list of expressions that are mappable. +/// Examples of these clauses are 'map' in +/// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from +/// in '#pragma omp target update...' directives. +template +class OMPMappableExprListClause : public OMPVarListClause, + public OMPClauseMappableExprCommon { + friend class OMPClauseReader; + + /// \brief Number of unique declarations in this clause. + unsigned NumUniqueDeclarations; + + /// \brief Number of component lists in this clause. + unsigned NumComponentLists; + + /// \brief Total number of components in this clause. + unsigned NumComponents; + +protected: + /// \brief Get the unique declarations that are in the trailing objects of the + /// class. + MutableArrayRef getUniqueDeclsRef() { + return MutableArrayRef( + static_cast(this)->template getTrailingObjects(), + NumUniqueDeclarations); + } + + /// \brief Get the unique declarations that are in the trailing objects of the + /// class. + ArrayRef getUniqueDeclsRef() const { + return ArrayRef( + static_cast(this) + ->template getTrailingObjects(), + NumUniqueDeclarations); + } + + /// \brief Set the unique declarations that are in the trailing objects of the + /// class. + void setUniqueDecls(ArrayRef UDs) { + assert(UDs.size() == NumUniqueDeclarations && + "Unexpected amount of unique declarations."); + std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin()); + } + + /// \brief Get the number of lists per declaration that are in the trailing + /// objects of the class. + MutableArrayRef getDeclNumListsRef() { + return MutableArrayRef( + static_cast(this)->template getTrailingObjects(), + NumUniqueDeclarations); + } + + /// \brief Get the number of lists per declaration that are in the trailing + /// objects of the class. + ArrayRef getDeclNumListsRef() const { + return ArrayRef( + static_cast(this)->template getTrailingObjects(), + NumUniqueDeclarations); + } + + /// \brief Set the number of lists per declaration that are in the trailing + /// objects of the class. + void setDeclNumLists(ArrayRef DNLs) { + assert(DNLs.size() == NumUniqueDeclarations && + "Unexpected amount of list numbers."); + std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin()); + } + + /// \brief Get the cumulative component lists sizes that are in the trailing + /// objects of the class. They are appended after the number of lists. + MutableArrayRef getComponentListSizesRef() { + return MutableArrayRef( + static_cast(this)->template getTrailingObjects() + + NumUniqueDeclarations, + NumComponentLists); + } + + /// \brief Get the cumulative component lists sizes that are in the trailing + /// objects of the class. They are appended after the number of lists. + ArrayRef getComponentListSizesRef() const { + return ArrayRef( + static_cast(this)->template getTrailingObjects() + + NumUniqueDeclarations, + NumComponentLists); + } + + /// \brief Set the cumulative component lists sizes that are in the trailing + /// objects of the class. + void setComponentListSizes(ArrayRef CLSs) { + assert(CLSs.size() == NumComponentLists && + "Unexpected amount of component lists."); + std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin()); + } + + /// \brief Get the components that are in the trailing objects of the class. + MutableArrayRef getComponentsRef() { + return MutableArrayRef( + static_cast(this) + ->template getTrailingObjects(), + NumComponents); + } + + /// \brief Get the components that are in the trailing objects of the class. + ArrayRef getComponentsRef() const { + return ArrayRef( + static_cast(this) + ->template getTrailingObjects(), + NumComponents); + } + + /// \brief Set the components that are in the trailing objects of the class. + /// This requires the list sizes so that it can also fill the original + /// expressions, which are the first component of each list. + void setComponents(ArrayRef Components, + ArrayRef CLSs) { + assert(Components.size() == NumComponents && + "Unexpected amount of component lists."); + assert(CLSs.size() == NumComponentLists && + "Unexpected amount of list sizes."); + std::copy(Components.begin(), Components.end(), getComponentsRef().begin()); + } + + /// \brief Fill the clause information from the list of declarations and + /// associated component lists. + void setClauseInfo(ArrayRef Declarations, + MappableExprComponentListsRef ComponentLists) { + // Perform some checks to make sure the data sizes are consistent with the + // information available when the clause was created. + assert(getUniqueDeclarationsTotalNumber(Declarations) == + NumUniqueDeclarations && + "Unexpected number of mappable expression info entries!"); + assert(getComponentsTotalNumber(ComponentLists) == NumComponents && + "Unexpected total number of components!"); + assert(Declarations.size() == ComponentLists.size() && + "Declaration and component lists size is not consistent!"); + assert(Declarations.size() == NumComponentLists && + "Unexpected declaration and component lists size!"); + + // Organize the components by declaration and retrieve the original + // expression. Original expressions are always the first component of the + // mappable component list. + llvm::DenseMap> + ComponentListMap; + { + auto CI = ComponentLists.begin(); + for (auto DI = Declarations.begin(), DE = Declarations.end(); DI != DE; + ++DI, ++CI) { + assert(!CI->empty() && "Invalid component list!"); + ComponentListMap[*DI].push_back(*CI); + } + } + + // Iterators of the target storage. + auto UniqueDeclarations = getUniqueDeclsRef(); + auto UDI = UniqueDeclarations.begin(); + + auto DeclNumLists = getDeclNumListsRef(); + auto DNLI = DeclNumLists.begin(); + + auto ComponentListSizes = getComponentListSizesRef(); + auto CLSI = ComponentListSizes.begin(); + + auto Components = getComponentsRef(); + auto CI = Components.begin(); + + // Variable to compute the accumulation of the number of components. + unsigned PrevSize = 0u; + + // Scan all the declarations and associated component lists. + for (auto &M : ComponentListMap) { + // The declaration. + auto *D = M.first; + // The component lists. + auto CL = M.second; + + // Initialize the entry. + *UDI = D; + ++UDI; + + *DNLI = CL.size(); + ++DNLI; + + // Obtain the cumulative sizes and concatenate all the components in the + // reserved storage. + for (auto C : CL) { + // Accumulate with the previous size. + PrevSize += C.size(); + + // Save the size. + *CLSI = PrevSize; + ++CLSI; + + // Append components after the current components iterator. + CI = std::copy(C.begin(), C.end(), CI); + } + } + } + + /// \brief Build a clause for \a NumUniqueDeclarations declarations, \a + /// NumComponentLists total component lists, and \a NumComponents total + /// components. + /// + /// \param K Kind of the clause. + /// \param StartLoc Starting location of the clause (the clause keyword). + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause - one + /// list for each expression in the clause. + /// \param NumComponents Total number of expression components in the clause. + /// + OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPVarListClause(K, StartLoc, LParenLoc, EndLoc, NumVars), + NumUniqueDeclarations(NumUniqueDeclarations), + NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} + +public: + /// \brief Return the number of unique base declarations in this clause. + unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; } + /// \brief Return the number of lists derived from the clause expressions. + unsigned getTotalComponentListNum() const { return NumComponentLists; } + /// \brief Return the total number of components in all lists derived from the + /// clause. + unsigned getTotalComponentsNum() const { return NumComponents; } + + /// \brief Iterator that browse the components by lists. It also allows + /// browsing components of a single declaration. + class const_component_lists_iterator + : public llvm::iterator_adaptor_base< + const_component_lists_iterator, + MappableExprComponentListRef::const_iterator, + std::forward_iterator_tag, MappableComponent, ptrdiff_t, + MappableComponent, MappableComponent> { + // The declaration the iterator currently refers to. + ArrayRef::iterator DeclCur; + + // The list number associated with the current declaration. + ArrayRef::iterator NumListsCur; + + // Remaining lists for the current declaration. + unsigned RemainingLists; + + // The cumulative size of the previous list, or zero if there is no previous + // list. + unsigned PrevListSize; + + // The cumulative sizes of the current list - it will delimit the remaining + // range of interest. + ArrayRef::const_iterator ListSizeCur; + ArrayRef::const_iterator ListSizeEnd; + + // Iterator to the end of the components storage. + MappableExprComponentListRef::const_iterator End; + + public: + /// \brief Construct an iterator that scans all lists. + explicit const_component_lists_iterator( + ArrayRef UniqueDecls, ArrayRef DeclsListNum, + ArrayRef CumulativeListSizes, + MappableExprComponentListRef Components) + : const_component_lists_iterator::iterator_adaptor_base( + Components.begin()), + DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()), + RemainingLists(0u), PrevListSize(0u), + ListSizeCur(CumulativeListSizes.begin()), + ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) { + assert(UniqueDecls.size() == DeclsListNum.size() && + "Inconsistent number of declarations and list sizes!"); + if (!DeclsListNum.empty()) + RemainingLists = *NumListsCur; + } + + /// \brief Construct an iterator that scan lists for a given declaration \a + /// Declaration. + explicit const_component_lists_iterator( + const ValueDecl *Declaration, ArrayRef UniqueDecls, + ArrayRef DeclsListNum, ArrayRef CumulativeListSizes, + MappableExprComponentListRef Components) + : const_component_lists_iterator(UniqueDecls, DeclsListNum, + CumulativeListSizes, Components) { + + // Look for the desired declaration. While we are looking for it, we + // update the state so that we know the component where a given list + // starts. + for (; DeclCur != UniqueDecls.end(); ++DeclCur, ++NumListsCur) { + if (*DeclCur == Declaration) + break; + + assert(*NumListsCur > 0 && "No lists associated with declaration??"); + + // Skip the lists associated with the current declaration, but save the + // last list size that was skipped. + std::advance(ListSizeCur, *NumListsCur - 1); + PrevListSize = *ListSizeCur; + ++ListSizeCur; + } + + // If we didn't find any declaration, advance the iterator to after the + // last component and set remaining lists to zero. + if (ListSizeCur == CumulativeListSizes.end()) { + this->I = End; + RemainingLists = 0u; + return; + } + + // Set the remaining lists with the total number of lists of the current + // declaration. + RemainingLists = *NumListsCur; + + // Adjust the list size end iterator to the end of the relevant range. + ListSizeEnd = ListSizeCur; + std::advance(ListSizeEnd, RemainingLists); + + // Given that the list sizes are cumulative, the index of the component + // that start the list is the size of the previous list. + std::advance(this->I, PrevListSize); + } + + // Return the array with the current list. The sizes are cumulative, so the + // array size is the difference between the current size and previous one. + std::pair + operator*() const { + assert(ListSizeCur != ListSizeEnd && "Invalid iterator!"); + return std::make_pair( + *DeclCur, + MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize)); + } + std::pair + operator->() const { + return **this; + } + + // Skip the components of the current list. + const_component_lists_iterator &operator++() { + assert(ListSizeCur != ListSizeEnd && RemainingLists && + "Invalid iterator!"); + + // If we don't have more lists just skip all the components. Otherwise, + // advance the iterator by the number of components in the current list. + if (std::next(ListSizeCur) == ListSizeEnd) { + this->I = End; + RemainingLists = 0; + } else { + std::advance(this->I, *ListSizeCur - PrevListSize); + PrevListSize = *ListSizeCur; + + // We are done with a declaration, move to the next one. + if (!(--RemainingLists)) { + ++DeclCur; + ++NumListsCur; + RemainingLists = *NumListsCur; + assert(RemainingLists && "No lists in the following declaration??"); + } + } + + ++ListSizeCur; + return *this; + } + }; + + typedef llvm::iterator_range + const_component_lists_range; + + /// \brief Iterators for all component lists. + const_component_lists_iterator component_lists_begin() const { + return const_component_lists_iterator( + getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(), + getComponentsRef()); + } + const_component_lists_iterator component_lists_end() const { + return const_component_lists_iterator( + ArrayRef(), ArrayRef(), ArrayRef(), + MappableExprComponentListRef(getComponentsRef().end(), + getComponentsRef().end())); + } + const_component_lists_range component_lists() const { + return {component_lists_begin(), component_lists_end()}; + } + + /// \brief Iterators for component lists associated with the provided + /// declaration. + const_component_lists_iterator + decl_component_lists_begin(const ValueDecl *VD) const { + return const_component_lists_iterator( + VD, getUniqueDeclsRef(), getDeclNumListsRef(), + getComponentListSizesRef(), getComponentsRef()); + } + const_component_lists_iterator decl_component_lists_end() const { + return component_lists_end(); + } + const_component_lists_range decl_component_lists(const ValueDecl *VD) const { + return {decl_component_lists_begin(VD), decl_component_lists_end()}; + } + + /// Iterators to access all the declarations, number of lists, list sizes, and + /// components. + typedef ArrayRef::iterator const_all_decls_iterator; + typedef llvm::iterator_range const_all_decls_range; + const_all_decls_range all_decls() const { + auto A = getUniqueDeclsRef(); + return const_all_decls_range(A.begin(), A.end()); + } + + typedef ArrayRef::iterator const_all_num_lists_iterator; + typedef llvm::iterator_range + const_all_num_lists_range; + const_all_num_lists_range all_num_lists() const { + auto A = getDeclNumListsRef(); + return const_all_num_lists_range(A.begin(), A.end()); + } + + typedef ArrayRef::iterator const_all_lists_sizes_iterator; + typedef llvm::iterator_range + const_all_lists_sizes_range; + const_all_lists_sizes_range all_lists_sizes() const { + auto A = getComponentListSizesRef(); + return const_all_lists_sizes_range(A.begin(), A.end()); + } + + typedef ArrayRef::iterator const_all_components_iterator; + typedef llvm::iterator_range + const_all_components_range; + const_all_components_range all_components() const { + auto A = getComponentsRef(); + return const_all_components_range(A.begin(), A.end()); + } +}; + /// \brief This represents clause 'map' in the '#pragma omp ...' /// directives. /// @@ -2731,16 +3279,33 @@ class OMPSIMDClause : public OMPClause { /// In this example directive '#pragma omp target' has clause 'map' /// with the variables 'a' and 'b'. /// -class OMPMapClause final : public OMPVarListClause, - private llvm::TrailingObjects { +class OMPMapClause final : public OMPMappableExprListClause, + private llvm::TrailingObjects< + OMPMapClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { friend TrailingObjects; friend OMPVarListClause; + friend OMPMappableExprListClause; friend class OMPClauseReader; + /// 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(); + } + /// \brief Map type modifier for the 'map' clause. OpenMPMapClauseKind MapTypeModifier; /// \brief Map type for the 'map' clause. OpenMPMapClauseKind MapType; + /// \brief Is this an implicit map type or not. + bool MapTypeIsImplicit; /// \brief Location of the map type. SourceLocation MapLoc; /// \brief Colon location. @@ -2767,30 +3332,49 @@ class OMPMapClause final : public OMPVarListClause, /// \brief Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } - /// \brief Build clause with number of variables \a N. + /// \brief Build a clause for \a NumVars listed expressions, \a + /// NumUniqueDeclarations declarations, \a NumComponentLists total component + /// lists, and \a NumComponents total expression components. /// /// \param MapTypeModifier Map type modifier. /// \param MapType Map type. + /// \param MapTypeIsImplicit Map type is inferred implicitly. /// \param MapLoc Location of the map type. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// \param N Number of the variables in the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. /// explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier, - OpenMPMapClauseKind MapType, SourceLocation MapLoc, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, N), - MapTypeModifier(MapTypeModifier), MapType(MapType), MapLoc(MapLoc) {} + OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, + SourceLocation MapLoc, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents), + MapTypeModifier(MapTypeModifier), MapType(MapType), + MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {} /// \brief Build an empty clause. /// - /// \param N Number of variables. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. /// - explicit OMPMapClause(unsigned N) - : OMPVarListClause(OMPC_map, SourceLocation(), - SourceLocation(), SourceLocation(), N), - MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapLoc() {} + explicit OMPMapClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents), + MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), + MapTypeIsImplicit(false), MapLoc() {} public: /// \brief Creates clause with a list of variables \a VL. @@ -2798,26 +3382,49 @@ class OMPMapClause final : public OMPVarListClause, /// \param C AST context. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// \param VL List of references to the variables. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. /// \param TypeModifier Map type modifier. /// \param Type Map type. + /// \param TypeIsImplicit Map type is inferred implicitly. /// \param TypeLoc Location of the map type. /// static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef VL, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef Vars, + ArrayRef Declarations, + MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, - OpenMPMapClauseKind Type, SourceLocation TypeLoc); - /// \brief Creates an empty clause with the place for \a N variables. + OpenMPMapClauseKind Type, bool TypeIsImplicit, + SourceLocation TypeLoc); + /// \brief Creates an empty clause with the place for for \a NumVars original + /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists + /// lists, and \a NumComponents expression components. /// /// \param C AST context. - /// \param N The number of variables. - /// - static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned N); + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); /// \brief Fetches mapping kind for the clause. OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } + /// \brief Is this an implicit map type? + /// We have to capture 'IsMapTypeImplicit' from the parser for more + /// informative error messages. It helps distinguish map(r) from + /// map(tofrom: r), which is important to print more helpful error + /// messages for some target directives. + bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; } + /// \brief Fetches the map type modifier for the clause. OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY { return MapTypeModifier; @@ -3193,6 +3800,553 @@ class OMPHintClause : public OMPClause { child_range children() { return child_range(&Hint, &Hint + 1); } }; +/// \brief This represents 'dist_schedule' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp distribute dist_schedule(static, 3) +/// \endcode +/// In this example directive '#pragma omp distribute' has 'dist_schedule' +/// clause with arguments 'static' and '3'. +/// +class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief A kind of the 'schedule' clause. + OpenMPDistScheduleClauseKind Kind; + /// \brief Start location of the schedule kind in source code. + SourceLocation KindLoc; + /// \brief Location of ',' (if any). + SourceLocation CommaLoc; + /// \brief Chunk size. + Expr *ChunkSize; + + /// \brief Set schedule kind. + /// + /// \param K Schedule kind. + /// + void setDistScheduleKind(OpenMPDistScheduleClauseKind K) { Kind = K; } + /// \brief Sets the location of '('. + /// + /// \param Loc Location of '('. + /// + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Set schedule kind start location. + /// + /// \param KLoc Schedule kind location. + /// + void setDistScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } + /// \brief Set location of ','. + /// + /// \param Loc Location of ','. + /// + void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; } + /// \brief Set chunk size. + /// + /// \param E Chunk size. + /// + void setChunkSize(Expr *E) { ChunkSize = E; } + +public: + /// \brief Build 'dist_schedule' clause with schedule kind \a Kind and chunk + /// size expression \a ChunkSize. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param KLoc Starting location of the argument. + /// \param CommaLoc Location of ','. + /// \param EndLoc Ending location of the clause. + /// \param Kind DistSchedule kind. + /// \param ChunkSize Chunk size. + /// \param HelperChunkSize Helper chunk size for combined directives. + /// + OMPDistScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation KLoc, SourceLocation CommaLoc, + SourceLocation EndLoc, + OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, + Stmt *HelperChunkSize) + : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { + setPreInitStmt(HelperChunkSize); + } + + /// \brief Build an empty clause. + /// + explicit OMPDistScheduleClause() + : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + OMPClauseWithPreInit(this), Kind(OMPC_DIST_SCHEDULE_unknown), + ChunkSize(nullptr) {} + + /// \brief Get kind of the clause. + /// + OpenMPDistScheduleClauseKind getDistScheduleKind() const { return Kind; } + /// \brief Get location of '('. + /// + SourceLocation getLParenLoc() { return LParenLoc; } + /// \brief Get kind location. + /// + SourceLocation getDistScheduleKindLoc() { return KindLoc; } + /// \brief Get location of ','. + /// + SourceLocation getCommaLoc() { return CommaLoc; } + /// \brief Get chunk size. + /// + Expr *getChunkSize() { return ChunkSize; } + /// \brief Get chunk size. + /// + const Expr *getChunkSize() const { return ChunkSize; } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_dist_schedule; + } + + child_range children() { + return child_range(reinterpret_cast(&ChunkSize), + reinterpret_cast(&ChunkSize) + 1); + } +}; + +/// \brief This represents 'defaultmap' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp target defaultmap(tofrom: scalar) +/// \endcode +/// In this example directive '#pragma omp target' has 'defaultmap' clause of kind +/// 'scalar' with modifier 'tofrom'. +/// +class OMPDefaultmapClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Modifiers for 'defaultmap' clause. + OpenMPDefaultmapClauseModifier Modifier; + /// \brief Locations of modifiers. + SourceLocation ModifierLoc; + /// \brief A kind of the 'defaultmap' clause. + OpenMPDefaultmapClauseKind Kind; + /// \brief Start location of the defaultmap kind in source code. + SourceLocation KindLoc; + + /// \brief Set defaultmap kind. + /// + /// \param K Defaultmap kind. + /// + void setDefaultmapKind(OpenMPDefaultmapClauseKind K) { Kind = K; } + /// \brief Set the defaultmap modifier. + /// + /// \param M Defaultmap modifier. + /// + void setDefaultmapModifier(OpenMPDefaultmapClauseModifier M) { + Modifier = M; + } + /// \brief Set location of the defaultmap modifier. + /// + void setDefaultmapModifierLoc(SourceLocation Loc) { + ModifierLoc = Loc; + } + /// \brief Sets the location of '('. + /// + /// \param Loc Location of '('. + /// + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Set defaultmap kind start location. + /// + /// \param KLoc Defaultmap kind location. + /// + void setDefaultmapKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } + +public: + /// \brief Build 'defaultmap' clause with defaultmap kind \a Kind + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param KLoc Starting location of the argument. + /// \param EndLoc Ending location of the clause. + /// \param Kind Defaultmap kind. + /// \param M The modifier applied to 'defaultmap' clause. + /// \param MLoc Location of the modifier + /// + OMPDefaultmapClause(SourceLocation StartLoc, SourceLocation LParenLoc, + 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) {} + + /// \brief Build an empty clause. + /// + explicit OMPDefaultmapClause() + : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()), + Modifier(OMPC_DEFAULTMAP_MODIFIER_unknown), + Kind(OMPC_DEFAULTMAP_unknown) {} + + /// \brief Get kind of the clause. + /// + OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } + /// \brief Get the modifier of the clause. + /// + OpenMPDefaultmapClauseModifier getDefaultmapModifier() const { + return Modifier; + } + /// \brief Get location of '('. + /// + SourceLocation getLParenLoc() { return LParenLoc; } + /// \brief Get kind location. + /// + SourceLocation getDefaultmapKindLoc() { return KindLoc; } + /// \brief Get the modifier location. + /// + SourceLocation getDefaultmapModifierLoc() const { + return ModifierLoc; + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_defaultmap; + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + +/// \brief This represents clause 'to' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target update to(a,b) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'to' +/// with the variables 'a' and 'b'. +/// +class OMPToClause final : public OMPMappableExprListClause, + private llvm::TrailingObjects< + OMPToClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { + friend TrailingObjects; + friend OMPVarListClause; + friend OMPMappableExprListClause; + friend class OMPClauseReader; + + /// 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(); + } + + /// \brief Build clause with number of variables \a NumVars. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_to, StartLoc, LParenLoc, EndLoc, NumVars, + NumUniqueDeclarations, NumComponentLists, + NumComponents) {} + + /// \brief Build an empty clause. + /// + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + +public: + /// \brief Creates clause with a list of variables \a Vars. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param 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 OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef Vars, + ArrayRef Declarations, + MappableExprComponentListsRef ComponentLists); + + /// \brief Creates an empty clause with the place for \a NumVars variables. + /// + /// \param C AST context. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_to; + } + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } +}; + +/// \brief This represents clause 'from' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target update from(a,b) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'from' +/// with the variables 'a' and 'b'. +/// +class OMPFromClause final + : public OMPMappableExprListClause, + private llvm::TrailingObjects< + OMPFromClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { + friend TrailingObjects; + friend OMPVarListClause; + friend OMPMappableExprListClause; + friend class OMPClauseReader; + + /// 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(); + } + + /// \brief Build clause with number of variables \a NumVars. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPFromClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_from, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents) {} + + /// \brief Build an empty clause. + /// + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPFromClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_from, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + +public: + /// \brief Creates clause with a list of variables \a Vars. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param 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 OMPFromClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef Vars, + ArrayRef Declarations, + MappableExprComponentListsRef ComponentLists); + + /// \brief Creates an empty clause with the place for \a NumVars variables. + /// + /// \param C AST context. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPFromClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_from; + } + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } +}; + +/// This represents clause 'use_device_ptr' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target data use_device_ptr(a,b) +/// \endcode +/// In this example directive '#pragma omp target data' has clause +/// 'use_device_ptr' with the variables 'a' and 'b'. +/// +class OMPUseDevicePtrClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend TrailingObjects; + friend OMPVarListClause; + friend class OMPClauseReader; + /// 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. + /// + OMPUseDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause(OMPC_use_device_ptr, StartLoc, + LParenLoc, EndLoc, N) {} + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPUseDevicePtrClause(unsigned N) + : OMPVarListClause( + OMPC_use_device_ptr, 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 variables. + /// + static OMPUseDevicePtrClause * + 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 OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_use_device_ptr; + } +}; + +/// This represents clause 'is_device_ptr' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target is_device_ptr(a,b) +/// \endcode +/// In this example directive '#pragma omp target' has clause +/// 'is_device_ptr' with the variables 'a' and 'b'. +/// +class OMPIsDevicePtrClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend TrailingObjects; + friend OMPVarListClause; + friend class OMPClauseReader; + /// 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. + /// + OMPIsDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause(OMPC_is_device_ptr, StartLoc, + LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPIsDevicePtrClause(unsigned N) + : OMPVarListClause( + OMPC_is_device_ptr, 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 variables. + /// + static OMPIsDevicePtrClause * + 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 OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_is_device_ptr; + } +}; } // end namespace clang #endif // LLVM_CLANG_AST_OPENMPCLAUSE_H diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def new file mode 100644 index 00000000000..82f494bec99 --- /dev/null +++ b/include/clang/AST/OperationKinds.def @@ -0,0 +1,406 @@ +//===--- OperationKinds.def - Operations Database ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file enumerates the different kinds of operations that can be +// performed by various expressions. +// +//===----------------------------------------------------------------------===// +// +/// @file OperationKinds.def +/// +/// In this file, each of the C/C++ operations is enumerated CAST_OPERATION, +/// BINARY_OPERATION or UNARY_OPERATION macro, each of which can be specified by +/// the code including this file. +/// +/// Macros had one or two arguments: +/// +/// Name: The name of the operation. Name (prefixed with CK_, UO_ or BO_) will +/// be the name of the corresponding enumerator (see OperationsKinds.h). +/// +/// Spelling: A string that provides a canonical spelling for the operation. + +#ifndef CAST_OPERATION +# define CAST_OPERATION(Name) +#endif + +#ifndef BINARY_OPERATION +# define BINARY_OPERATION(Name, Spelling) +#endif + +#ifndef UNARY_OPERATION +# define UNARY_OPERATION(Name, Spelling) +#endif + +//===- Cast Operations ---------------------------------------------------===// + +/// CK_Dependent - A conversion which cannot yet be analyzed because +/// either the expression or target type is dependent. These are +/// created only for explicit casts; dependent ASTs aren't required +/// to even approximately type-check. +/// (T*) malloc(sizeof(T)) +/// reinterpret_cast(A::alloc()); +CAST_OPERATION(Dependent) + +/// CK_BitCast - A conversion which causes a bit pattern of one type +/// to be reinterpreted as a bit pattern of another type. Generally +/// the operands must have equivalent size and unrelated types. +/// +/// The pointer conversion char* -> int* is a bitcast. A conversion +/// from any pointer type to a C pointer type is a bitcast unless +/// it's actually BaseToDerived or DerivedToBase. A conversion to a +/// block pointer or ObjC pointer type is a bitcast only if the +/// operand has the same type kind; otherwise, it's one of the +/// specialized casts below. +/// +/// Vector coercions are bitcasts. +CAST_OPERATION(BitCast) + +/// CK_LValueBitCast - A conversion which reinterprets the address of +/// an l-value as an l-value of a different kind. Used for +/// reinterpret_casts of l-value expressions to reference types. +/// bool b; reinterpret_cast(b) = 'a'; +CAST_OPERATION(LValueBitCast) + +/// CK_LValueToRValue - A conversion which causes the extraction of +/// an r-value from the operand gl-value. The result of an r-value +/// conversion is always unqualified. +CAST_OPERATION(LValueToRValue) + +/// CK_NoOp - A conversion which does not affect the type other than +/// (possibly) adding qualifiers. +/// int -> int +/// char** -> const char * const * +CAST_OPERATION(NoOp) + +/// CK_BaseToDerived - A conversion from a C++ class pointer/reference +/// to a derived class pointer/reference. +/// B *b = static_cast(a); +CAST_OPERATION(BaseToDerived) + +/// CK_DerivedToBase - A conversion from a C++ class pointer +/// to a base class pointer. +/// A *a = new B(); +CAST_OPERATION(DerivedToBase) + +/// CK_UncheckedDerivedToBase - A conversion from a C++ class +/// pointer/reference to a base class that can assume that the +/// derived pointer is not null. +/// const A &a = B(); +/// b->method_from_a(); +CAST_OPERATION(UncheckedDerivedToBase) + +/// CK_Dynamic - A C++ dynamic_cast. +CAST_OPERATION(Dynamic) + +/// CK_ToUnion - The GCC cast-to-union extension. +/// int -> union { int x; float y; } +/// float -> union { int x; float y; } +CAST_OPERATION(ToUnion) + +/// CK_ArrayToPointerDecay - Array to pointer decay. +/// int[10] -> int* +/// char[5][6] -> char(*)[6] +CAST_OPERATION(ArrayToPointerDecay) + +/// CK_FunctionToPointerDecay - Function to pointer decay. +/// void(int) -> void(*)(int) +CAST_OPERATION(FunctionToPointerDecay) + +/// CK_NullToPointer - Null pointer constant to pointer, ObjC +/// pointer, or block pointer. +/// (void*) 0 +/// void (^block)() = 0; +CAST_OPERATION(NullToPointer) + +/// CK_NullToMemberPointer - Null pointer constant to member pointer. +/// int A::*mptr = 0; +/// int (A::*fptr)(int) = nullptr; +CAST_OPERATION(NullToMemberPointer) + +/// CK_BaseToDerivedMemberPointer - Member pointer in base class to +/// member pointer in derived class. +/// int B::*mptr = &A::member; +CAST_OPERATION(BaseToDerivedMemberPointer) + +/// CK_DerivedToBaseMemberPointer - Member pointer in derived class to +/// member pointer in base class. +/// int A::*mptr = static_cast(&B::member); +CAST_OPERATION(DerivedToBaseMemberPointer) + +/// CK_MemberPointerToBoolean - Member pointer to boolean. A check +/// against the null member pointer. +CAST_OPERATION(MemberPointerToBoolean) + +/// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a +/// different kind of member pointer. C++ forbids this from +/// crossing between function and object types, but otherwise does +/// not restrict it. However, the only operation that is permitted +/// on a "punned" member pointer is casting it back to the original +/// type, which is required to be a lossless operation (although +/// many ABIs do not guarantee this on all possible intermediate types). +CAST_OPERATION(ReinterpretMemberPointer) + +/// CK_UserDefinedConversion - Conversion using a user defined type +/// conversion function. +/// struct A { operator int(); }; int i = int(A()); +CAST_OPERATION(UserDefinedConversion) + +/// CK_ConstructorConversion - Conversion by constructor. +/// struct A { A(int); }; A a = A(10); +CAST_OPERATION(ConstructorConversion) + +/// CK_IntegralToPointer - Integral to pointer. A special kind of +/// reinterpreting conversion. Applies to normal, ObjC, and block +/// pointers. +/// (char*) 0x1001aab0 +/// reinterpret_cast(0) +CAST_OPERATION(IntegralToPointer) + +/// CK_PointerToIntegral - Pointer to integral. A special kind of +/// reinterpreting conversion. Applies to normal, ObjC, and block +/// pointers. +/// (intptr_t) "help!" +CAST_OPERATION(PointerToIntegral) + +/// CK_PointerToBoolean - Pointer to boolean conversion. A check +/// against null. Applies to normal, ObjC, and block pointers. +CAST_OPERATION(PointerToBoolean) + +/// CK_ToVoid - Cast to void, discarding the computed value. +/// (void) malloc(2048) +CAST_OPERATION(ToVoid) + +/// CK_VectorSplat - A conversion from an arithmetic type to a +/// vector of that element type. Fills all elements ("splats") with +/// the source value. +/// __attribute__((ext_vector_type(4))) int v = 5; +CAST_OPERATION(VectorSplat) + +/// CK_IntegralCast - A cast between integral types (other than to +/// boolean). Variously a bitcast, a truncation, a sign-extension, +/// or a zero-extension. +/// long l = 5; +/// (unsigned) i +CAST_OPERATION(IntegralCast) + +/// CK_IntegralToBoolean - Integral to boolean. A check against zero. +/// (bool) i +CAST_OPERATION(IntegralToBoolean) + +/// CK_IntegralToFloating - Integral to floating point. +/// float f = i; +CAST_OPERATION(IntegralToFloating) + +/// CK_FloatingToIntegral - Floating point to integral. Rounds +/// towards zero, discarding any fractional component. +/// (int) f +CAST_OPERATION(FloatingToIntegral) + +/// CK_FloatingToBoolean - Floating point to boolean. +/// (bool) f +CAST_OPERATION(FloatingToBoolean) + +// CK_BooleanToSignedIntegral - Convert a boolean to -1 or 0 for true and +// false, respectively. +CAST_OPERATION(BooleanToSignedIntegral) + +/// CK_FloatingCast - Casting between floating types of different size. +/// (double) f +/// (float) ld +CAST_OPERATION(FloatingCast) + +/// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an +/// Objective-C pointer. +CAST_OPERATION(CPointerToObjCPointerCast) + +/// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an +/// ObjC pointer. +CAST_OPERATION(BlockPointerToObjCPointerCast) + +/// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer +/// to a block pointer. Block-to-block casts are bitcasts. +CAST_OPERATION(AnyPointerToBlockPointerCast) + +/// \brief Converting between two Objective-C object types, which +/// can occur when performing reference binding to an Objective-C +/// object. +CAST_OPERATION(ObjCObjectLValueCast) + +/// \brief A conversion of a floating point real to a floating point +/// complex of the original type. Injects the value as the real +/// component with a zero imaginary component. +/// float -> _Complex float +CAST_OPERATION(FloatingRealToComplex) + +/// \brief Converts a floating point complex to floating point real +/// of the source's element type. Just discards the imaginary +/// component. +/// _Complex long double -> long double +CAST_OPERATION(FloatingComplexToReal) + +/// \brief Converts a floating point complex to bool by comparing +/// against 0+0i. +CAST_OPERATION(FloatingComplexToBoolean) + +/// \brief Converts between different floating point complex types. +/// _Complex float -> _Complex double +CAST_OPERATION(FloatingComplexCast) + +/// \brief Converts from a floating complex to an integral complex. +/// _Complex float -> _Complex int +CAST_OPERATION(FloatingComplexToIntegralComplex) + +/// \brief Converts from an integral real to an integral complex +/// whose element type matches the source. Injects the value as +/// the real component with a zero imaginary component. +/// long -> _Complex long +CAST_OPERATION(IntegralRealToComplex) + +/// \brief Converts an integral complex to an integral real of the +/// source's element type by discarding the imaginary component. +/// _Complex short -> short +CAST_OPERATION(IntegralComplexToReal) + +/// \brief Converts an integral complex to bool by comparing against +/// 0+0i. +CAST_OPERATION(IntegralComplexToBoolean) + +/// \brief Converts between different integral complex types. +/// _Complex char -> _Complex long long +/// _Complex unsigned int -> _Complex signed int +CAST_OPERATION(IntegralComplexCast) + +/// \brief Converts from an integral complex to a floating complex. +/// _Complex unsigned -> _Complex float +CAST_OPERATION(IntegralComplexToFloatingComplex) + +/// \brief [ARC] Produces a retainable object pointer so that it may +/// be consumed, e.g. by being passed to a consuming parameter. +/// Calls objc_retain. +CAST_OPERATION(ARCProduceObject) + +/// \brief [ARC] Consumes a retainable object pointer that has just +/// been produced, e.g. as the return value of a retaining call. +/// Enters a cleanup to call objc_release at some indefinite time. +CAST_OPERATION(ARCConsumeObject) + +/// \brief [ARC] Reclaim a retainable object pointer object that may +/// have been produced and autoreleased as part of a function return +/// sequence. +CAST_OPERATION(ARCReclaimReturnedObject) + +/// \brief [ARC] Causes a value of block type to be copied to the +/// heap, if it is not already there. A number of other operations +/// in ARC cause blocks to be copied; this is for cases where that +/// would not otherwise be guaranteed, such as when casting to a +/// non-block pointer type. +CAST_OPERATION(ARCExtendBlockObject) + +/// \brief Converts from _Atomic(T) to T. +CAST_OPERATION(AtomicToNonAtomic) +/// \brief Converts from T to _Atomic(T). +CAST_OPERATION(NonAtomicToAtomic) + +/// \brief Causes a block literal to by copied to the heap and then +/// autoreleased. +/// +/// This particular cast kind is used for the conversion from a C++11 +/// lambda expression to a block pointer. +CAST_OPERATION(CopyAndAutoreleaseBlockObject) + +// Convert a builtin function to a function pointer; only allowed in the +// callee of a call expression. +CAST_OPERATION(BuiltinFnToFnPtr) + +// Convert a zero value for OpenCL event_t initialization. +CAST_OPERATION(ZeroToOCLEvent) + +// Convert a pointer to a different address space. +CAST_OPERATION(AddressSpaceConversion) + + +//===- Binary Operations -------------------------------------------------===// +// Operators listed in order of precedence. +// Note that additions to this should also update the StmtVisitor class. + +// [C++ 5.5] Pointer-to-member operators. +BINARY_OPERATION(PtrMemD, ".*") +BINARY_OPERATION(PtrMemI, "->*") +// [C99 6.5.5] Multiplicative operators. +BINARY_OPERATION(Mul, "*") +BINARY_OPERATION(Div, "/") +BINARY_OPERATION(Rem, "%") +// [C99 6.5.6] Additive operators. +BINARY_OPERATION(Add, "+") +BINARY_OPERATION(Sub, "-") +// [C99 6.5.7] Bitwise shift operators. +BINARY_OPERATION(Shl, "<<") +BINARY_OPERATION(Shr, ">>") +// [C99 6.5.8] Relational operators. +BINARY_OPERATION(LT, "<") +BINARY_OPERATION(GT, ">") +BINARY_OPERATION(LE, "<=") +BINARY_OPERATION(GE, ">=") +// [C99 6.5.9] Equality operators. +BINARY_OPERATION(EQ, "==") +BINARY_OPERATION(NE, "!=") +// [C99 6.5.10] Bitwise AND operator. +BINARY_OPERATION(And, "&") +// [C99 6.5.11] Bitwise XOR operator. +BINARY_OPERATION(Xor, "^") +// [C99 6.5.12] Bitwise OR operator. +BINARY_OPERATION(Or, "|") +// [C99 6.5.13] Logical AND operator. +BINARY_OPERATION(LAnd, "&&") +// [C99 6.5.14] Logical OR operator. +BINARY_OPERATION(LOr, "||") +// [C99 6.5.16] Assignment operators. +BINARY_OPERATION(Assign, "=") +BINARY_OPERATION(MulAssign, "*=") +BINARY_OPERATION(DivAssign, "/=") +BINARY_OPERATION(RemAssign, "%=") +BINARY_OPERATION(AddAssign, "+=") +BINARY_OPERATION(SubAssign, "-=") +BINARY_OPERATION(ShlAssign, "<<=") +BINARY_OPERATION(ShrAssign, ">>=") +BINARY_OPERATION(AndAssign, "&=") +BINARY_OPERATION(XorAssign, "^=") +BINARY_OPERATION(OrAssign, "|=") +// [C99 6.5.17] Comma operator. +BINARY_OPERATION(Comma, ",") + + +//===- Unary Operations ---------------------------------------------------===// +// Note that additions to this should also update the StmtVisitor class. + +// [C99 6.5.2.4] Postfix increment and decrement +UNARY_OPERATION(PostInc, "++") +UNARY_OPERATION(PostDec, "--") +// [C99 6.5.3.1] Prefix increment and decrement +UNARY_OPERATION(PreInc, "++") +UNARY_OPERATION(PreDec, "--") +// [C99 6.5.3.2] Address and indirection +UNARY_OPERATION(AddrOf, "&") +UNARY_OPERATION(Deref, "*") +// [C99 6.5.3.3] Unary arithmetic +UNARY_OPERATION(Plus, "+") +UNARY_OPERATION(Minus, "-") +UNARY_OPERATION(Not, "~") +UNARY_OPERATION(LNot, "!") +// "__real expr"/"__imag expr" Extension. +UNARY_OPERATION(Real, "__real") +UNARY_OPERATION(Imag, "__imag") +// __extension__ marker. +UNARY_OPERATION(Extension, "__extension__") +// [C++ Coroutines] co_await operator +UNARY_OPERATION(Coawait, "co_await") + +#undef CAST_OPERATION +#undef BINARY_OPERATION +#undef UNARY_OPERATION diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index 102bbc21edb..00f060fe9e3 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -19,327 +19,20 @@ namespace clang { /// CastKind - The kind of operation required for a conversion. enum CastKind { - /// CK_Dependent - A conversion which cannot yet be analyzed because - /// either the expression or target type is dependent. These are - /// created only for explicit casts; dependent ASTs aren't required - /// to even approximately type-check. - /// (T*) malloc(sizeof(T)) - /// reinterpret_cast(A::alloc()); - CK_Dependent, - - /// CK_BitCast - A conversion which causes a bit pattern of one type - /// to be reinterpreted as a bit pattern of another type. Generally - /// the operands must have equivalent size and unrelated types. - /// - /// The pointer conversion char* -> int* is a bitcast. A conversion - /// from any pointer type to a C pointer type is a bitcast unless - /// it's actually BaseToDerived or DerivedToBase. A conversion to a - /// block pointer or ObjC pointer type is a bitcast only if the - /// operand has the same type kind; otherwise, it's one of the - /// specialized casts below. - /// - /// Vector coercions are bitcasts. - CK_BitCast, - - /// CK_LValueBitCast - A conversion which reinterprets the address of - /// an l-value as an l-value of a different kind. Used for - /// reinterpret_casts of l-value expressions to reference types. - /// bool b; reinterpret_cast(b) = 'a'; - CK_LValueBitCast, - - /// CK_LValueToRValue - A conversion which causes the extraction of - /// an r-value from the operand gl-value. The result of an r-value - /// conversion is always unqualified. - CK_LValueToRValue, - - /// CK_NoOp - A conversion which does not affect the type other than - /// (possibly) adding qualifiers. - /// int -> int - /// char** -> const char * const * - CK_NoOp, - - /// CK_BaseToDerived - A conversion from a C++ class pointer/reference - /// to a derived class pointer/reference. - /// B *b = static_cast(a); - CK_BaseToDerived, - - /// CK_DerivedToBase - A conversion from a C++ class pointer - /// to a base class pointer. - /// A *a = new B(); - CK_DerivedToBase, - - /// CK_UncheckedDerivedToBase - A conversion from a C++ class - /// pointer/reference to a base class that can assume that the - /// derived pointer is not null. - /// const A &a = B(); - /// b->method_from_a(); - CK_UncheckedDerivedToBase, - - /// CK_Dynamic - A C++ dynamic_cast. - CK_Dynamic, - - /// CK_ToUnion - The GCC cast-to-union extension. - /// int -> union { int x; float y; } - /// float -> union { int x; float y; } - CK_ToUnion, - - /// CK_ArrayToPointerDecay - Array to pointer decay. - /// int[10] -> int* - /// char[5][6] -> char(*)[6] - CK_ArrayToPointerDecay, - - /// CK_FunctionToPointerDecay - Function to pointer decay. - /// void(int) -> void(*)(int) - CK_FunctionToPointerDecay, - - /// CK_NullToPointer - Null pointer constant to pointer, ObjC - /// pointer, or block pointer. - /// (void*) 0 - /// void (^block)() = 0; - CK_NullToPointer, - - /// CK_NullToMemberPointer - Null pointer constant to member pointer. - /// int A::*mptr = 0; - /// int (A::*fptr)(int) = nullptr; - CK_NullToMemberPointer, - - /// CK_BaseToDerivedMemberPointer - Member pointer in base class to - /// member pointer in derived class. - /// int B::*mptr = &A::member; - CK_BaseToDerivedMemberPointer, - - /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to - /// member pointer in base class. - /// int A::*mptr = static_cast(&B::member); - CK_DerivedToBaseMemberPointer, - - /// CK_MemberPointerToBoolean - Member pointer to boolean. A check - /// against the null member pointer. - CK_MemberPointerToBoolean, - - /// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a - /// different kind of member pointer. C++ forbids this from - /// crossing between function and object types, but otherwise does - /// not restrict it. However, the only operation that is permitted - /// on a "punned" member pointer is casting it back to the original - /// type, which is required to be a lossless operation (although - /// many ABIs do not guarantee this on all possible intermediate types). - CK_ReinterpretMemberPointer, - - /// CK_UserDefinedConversion - Conversion using a user defined type - /// conversion function. - /// struct A { operator int(); }; int i = int(A()); - CK_UserDefinedConversion, - - /// CK_ConstructorConversion - Conversion by constructor. - /// struct A { A(int); }; A a = A(10); - CK_ConstructorConversion, - - /// CK_IntegralToPointer - Integral to pointer. A special kind of - /// reinterpreting conversion. Applies to normal, ObjC, and block - /// pointers. - /// (char*) 0x1001aab0 - /// reinterpret_cast(0) - CK_IntegralToPointer, - - /// CK_PointerToIntegral - Pointer to integral. A special kind of - /// reinterpreting conversion. Applies to normal, ObjC, and block - /// pointers. - /// (intptr_t) "help!" - CK_PointerToIntegral, - - /// CK_PointerToBoolean - Pointer to boolean conversion. A check - /// against null. Applies to normal, ObjC, and block pointers. - CK_PointerToBoolean, - - /// CK_ToVoid - Cast to void, discarding the computed value. - /// (void) malloc(2048) - CK_ToVoid, - - /// CK_VectorSplat - A conversion from an arithmetic type to a - /// vector of that element type. Fills all elements ("splats") with - /// the source value. - /// __attribute__((ext_vector_type(4))) int v = 5; - CK_VectorSplat, - - /// CK_IntegralCast - A cast between integral types (other than to - /// boolean). Variously a bitcast, a truncation, a sign-extension, - /// or a zero-extension. - /// long l = 5; - /// (unsigned) i - CK_IntegralCast, - - /// CK_IntegralToBoolean - Integral to boolean. A check against zero. - /// (bool) i - CK_IntegralToBoolean, - - /// CK_IntegralToFloating - Integral to floating point. - /// float f = i; - CK_IntegralToFloating, - - /// CK_FloatingToIntegral - Floating point to integral. Rounds - /// towards zero, discarding any fractional component. - /// (int) f - CK_FloatingToIntegral, - - /// CK_FloatingToBoolean - Floating point to boolean. - /// (bool) f - CK_FloatingToBoolean, - - // CK_BooleanToSignedIntegral - Convert a boolean to -1 or 0 for true and - // false, respectively. - CK_BooleanToSignedIntegral, - - /// CK_FloatingCast - Casting between floating types of different size. - /// (double) f - /// (float) ld - CK_FloatingCast, - - /// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an - /// Objective-C pointer. - CK_CPointerToObjCPointerCast, - - /// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an - /// ObjC pointer. - CK_BlockPointerToObjCPointerCast, - - /// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer - /// to a block pointer. Block-to-block casts are bitcasts. - CK_AnyPointerToBlockPointerCast, - - /// \brief Converting between two Objective-C object types, which - /// can occur when performing reference binding to an Objective-C - /// object. - CK_ObjCObjectLValueCast, - - /// \brief A conversion of a floating point real to a floating point - /// complex of the original type. Injects the value as the real - /// component with a zero imaginary component. - /// float -> _Complex float - CK_FloatingRealToComplex, - - /// \brief Converts a floating point complex to floating point real - /// of the source's element type. Just discards the imaginary - /// component. - /// _Complex long double -> long double - CK_FloatingComplexToReal, - - /// \brief Converts a floating point complex to bool by comparing - /// against 0+0i. - CK_FloatingComplexToBoolean, - - /// \brief Converts between different floating point complex types. - /// _Complex float -> _Complex double - CK_FloatingComplexCast, - - /// \brief Converts from a floating complex to an integral complex. - /// _Complex float -> _Complex int - CK_FloatingComplexToIntegralComplex, - - /// \brief Converts from an integral real to an integral complex - /// whose element type matches the source. Injects the value as - /// the real component with a zero imaginary component. - /// long -> _Complex long - CK_IntegralRealToComplex, - - /// \brief Converts an integral complex to an integral real of the - /// source's element type by discarding the imaginary component. - /// _Complex short -> short - CK_IntegralComplexToReal, - - /// \brief Converts an integral complex to bool by comparing against - /// 0+0i. - CK_IntegralComplexToBoolean, - - /// \brief Converts between different integral complex types. - /// _Complex char -> _Complex long long - /// _Complex unsigned int -> _Complex signed int - CK_IntegralComplexCast, - - /// \brief Converts from an integral complex to a floating complex. - /// _Complex unsigned -> _Complex float - CK_IntegralComplexToFloatingComplex, - - /// \brief [ARC] Produces a retainable object pointer so that it may - /// be consumed, e.g. by being passed to a consuming parameter. - /// Calls objc_retain. - CK_ARCProduceObject, - - /// \brief [ARC] Consumes a retainable object pointer that has just - /// been produced, e.g. as the return value of a retaining call. - /// Enters a cleanup to call objc_release at some indefinite time. - CK_ARCConsumeObject, - - /// \brief [ARC] Reclaim a retainable object pointer object that may - /// have been produced and autoreleased as part of a function return - /// sequence. - CK_ARCReclaimReturnedObject, - - /// \brief [ARC] Causes a value of block type to be copied to the - /// heap, if it is not already there. A number of other operations - /// in ARC cause blocks to be copied; this is for cases where that - /// would not otherwise be guaranteed, such as when casting to a - /// non-block pointer type. - CK_ARCExtendBlockObject, - - /// \brief Converts from _Atomic(T) to T. - CK_AtomicToNonAtomic, - /// \brief Converts from T to _Atomic(T). - CK_NonAtomicToAtomic, - - /// \brief Causes a block literal to by copied to the heap and then - /// autoreleased. - /// - /// This particular cast kind is used for the conversion from a C++11 - /// lambda expression to a block pointer. - CK_CopyAndAutoreleaseBlockObject, - - // Convert a builtin function to a function pointer; only allowed in the - // callee of a call expression. - CK_BuiltinFnToFnPtr, - - // Convert a zero value for OpenCL event_t initialization. - CK_ZeroToOCLEvent, - - // Convert a pointer to a different address space. - CK_AddressSpaceConversion +#define CAST_OPERATION(Name) CK_##Name, +#include "clang/AST/OperationKinds.def" }; static const CastKind CK_Invalid = static_cast(-1); enum BinaryOperatorKind { - // Operators listed in order of precedence. - // Note that additions to this should also update the StmtVisitor class. - BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators. - BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators. - BO_Add, BO_Sub, // [C99 6.5.6] Additive operators. - BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators. - BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators. - BO_EQ, BO_NE, // [C99 6.5.9] Equality operators. - BO_And, // [C99 6.5.10] Bitwise AND operator. - BO_Xor, // [C99 6.5.11] Bitwise XOR operator. - BO_Or, // [C99 6.5.12] Bitwise OR operator. - BO_LAnd, // [C99 6.5.13] Logical AND operator. - BO_LOr, // [C99 6.5.14] Logical OR operator. - BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators. - BO_DivAssign, BO_RemAssign, - BO_AddAssign, BO_SubAssign, - BO_ShlAssign, BO_ShrAssign, - BO_AndAssign, BO_XorAssign, - BO_OrAssign, - BO_Comma // [C99 6.5.17] Comma operator. +#define BINARY_OPERATION(Name, Spelling) BO_##Name, +#include "clang/AST/OperationKinds.def" }; enum UnaryOperatorKind { - // Note that additions to this should also update the StmtVisitor class. - UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement - UO_PreInc, UO_PreDec, // [C99 6.5.3.1] Prefix increment and decrement - UO_AddrOf, UO_Deref, // [C99 6.5.3.2] Address and indirection - UO_Plus, UO_Minus, // [C99 6.5.3.3] Unary arithmetic - UO_Not, UO_LNot, // [C99 6.5.3.3] Unary arithmetic - UO_Real, UO_Imag, // "__real expr"/"__imag expr" Extension. - UO_Extension, // __extension__ marker. - UO_Coawait // [C++ Coroutines] co_await operator +#define UNARY_OPERATION(Name, Spelling) UO_##Name, +#include "clang/AST/OperationKinds.def" }; /// \brief The kind of bridging performed by the Objective-C bridge cast. @@ -355,6 +48,6 @@ enum ObjCBridgeCastKind { OBC_BridgeRetained }; -} +} // end namespace clang #endif diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 8ab3f61703a..274df220e16 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -32,20 +32,35 @@ class PrinterHelper { /// \brief Describes how types, statements, expressions, and /// declarations should be printed. +/// +/// This type is intended to be small and suitable for passing by value. +/// It is very frequently copied. struct PrintingPolicy { - /// \brief Create a default printing policy for C. + /// \brief Create a default printing policy for the specified language. PrintingPolicy(const LangOptions &LO) - : LangOpts(LO), Indentation(2), SuppressSpecifiers(false), - SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), + : Indentation(2), SuppressSpecifiers(false), + SuppressTagKeyword(LO.CPlusPlus), + IncludeTagDefinition(false), SuppressScope(false), SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), - Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), + SuppressTemplateArgsInCXXConstructors(false), + Bool(LO.Bool), Restrict(LO.C99), + Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11), + UseVoidForZeroParams(!LO.CPlusPlus), + TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false) { } - /// \brief What language we're printing. - LangOptions LangOpts; + /// \brief 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 construct). This should not be used if a real LangOptions + /// object is available. + void adjustForCPlusPlus() { + SuppressTagKeyword = true; + Bool = true; + UseVoidForZeroParams = false; + } /// \brief The number of spaces to use to indent each line. unsigned Indentation : 8; @@ -76,15 +91,15 @@ struct PrintingPolicy { /// \endcode bool SuppressTagKeyword : 1; - /// \brief Whether type printing should skip printing the actual tag type. + /// \brief When true, include the body of a tag definition. /// - /// This is used when the caller needs to print a tag definition in front - /// of the type, as in constructs like the following: + /// This is used to place the definition of a struct + /// in the middle of another declaration as with: /// /// \code /// typedef struct { int x, y; } Point; /// \endcode - bool SuppressTag : 1; + bool IncludeTagDefinition : 1; /// \brief Suppresses printing of scope specifiers. bool SuppressScope : 1; @@ -136,11 +151,28 @@ struct PrintingPolicy { /// \brief When true, suppress printing of lifetime qualifier in /// ARC. unsigned SuppressLifetimeQualifiers : 1; - - /// \brief Whether we can use 'bool' rather than '_Bool', even if the language - /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). + + /// When true, suppresses printing template arguments in names of C++ + /// constructors. + unsigned SuppressTemplateArgsInCXXConstructors : 1; + + /// \brief Whether we can use 'bool' rather than '_Bool' (even if the language + /// doesn't actually have 'bool', because, e.g., it is defined as a macro). unsigned Bool : 1; + /// \brief Whether we can use 'restrict' rather than '__restrict'. + unsigned Restrict : 1; + + /// \brief Whether we can use 'alignof' rather than '__alignof'. + unsigned Alignof : 1; + + /// \brief Whether we can use '_Alignof' rather than '__alignof'. + unsigned UnderscoreAlignof : 1; + + /// \brief Whether we should use '(void)' rather than '()' for a function + /// prototype with zero parameters. + unsigned UseVoidForZeroParams : 1; + /// \brief Provide a 'terse' output. /// /// For example, in this mode we don't print function bodies, class members, diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 667f23520eb..7a39c3b2539 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -71,10 +71,7 @@ class ASTRecordLayout { CharUnits RequiredAlignment; /// FieldOffsets - Array of field offsets in bits. - uint64_t *FieldOffsets; - - // FieldCount - Number of fields. - unsigned FieldCount; + ASTVector FieldOffsets; /// CXXRecordLayoutInfo - Contains C++ specific layout information. struct CXXRecordLayoutInfo { @@ -104,10 +101,10 @@ class ASTRecordLayout { /// a primary base class. bool HasExtendableVFPtr : 1; - /// HasZeroSizedSubObject - True if this class contains a zero sized member - /// or base or a base with a zero sized member or base. Only used for - /// MS-ABI. - bool HasZeroSizedSubObject : 1; + /// EndsWithZeroSizedObject - True if this class contains a zero sized + /// member or base or a base with a zero sized member or base. + /// Only used for MS-ABI. + bool EndsWithZeroSizedObject : 1; /// \brief True if this class is zero sized or first base is zero sized or /// has this property. Only used for MS-ABI. @@ -136,9 +133,8 @@ class ASTRecordLayout { friend class ASTContext; ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, - CharUnits requiredAlignment, - CharUnits datasize, const uint64_t *fieldoffsets, - unsigned fieldcount); + CharUnits requiredAlignment, CharUnits datasize, + ArrayRef fieldoffsets); // Constructor for C++ records. typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; @@ -148,13 +144,13 @@ class ASTRecordLayout { bool hasOwnVFPtr, bool hasExtendableVFPtr, CharUnits vbptroffset, CharUnits datasize, - const uint64_t *fieldoffsets, unsigned fieldcount, + ArrayRef fieldoffsets, CharUnits nonvirtualsize, CharUnits nonvirtualalignment, CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, const CXXRecordDecl *BaseSharingVBPtr, - bool HasZeroSizedSubObject, + bool EndsWithZeroSizedObject, bool LeadsWithZeroSizedBase, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets); @@ -174,12 +170,11 @@ class ASTRecordLayout { CharUnits getSize() const { return Size; } /// getFieldCount - Get the number of fields in the layout. - unsigned getFieldCount() const { return FieldCount; } + unsigned getFieldCount() const { return FieldOffsets.size(); } /// getFieldOffset - Get the offset of the given field index, in /// bits. uint64_t getFieldOffset(unsigned FieldNo) const { - assert (FieldNo < FieldCount && "Invalid Field No"); return FieldOffsets[FieldNo]; } @@ -283,8 +278,8 @@ class ASTRecordLayout { return RequiredAlignment; } - bool hasZeroSizedSubObject() const { - return CXXInfo && CXXInfo->HasZeroSizedSubObject; + bool endsWithZeroSizedObject() const { + return CXXInfo && CXXInfo->EndsWithZeroSizedObject; } bool leadsWithZeroSizedBase() const { diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0c25a45c1ce..f918b830d42 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -72,8 +72,8 @@ namespace clang { return false; \ } while (0) -/// \brief A class that does preorder depth-first traversal on the -/// entire Clang AST and visits each node. +/// \brief A class that does preordor or postorder +/// depth-first traversal on the entire Clang AST and visits each node. /// /// This class performs three distinct tasks: /// 1. traverse the AST (i.e. go to each node); @@ -133,13 +133,19 @@ namespace clang { /// to return true, in which case all known implicit and explicit /// instantiations will be visited at the same time as the pattern /// from which they were produced. +/// +/// By default, this visitor preorder traverses the AST. If postorder traversal +/// is needed, the \c shouldTraversePostOrder method needs to be overriden +/// to return \c true. template class RecursiveASTVisitor { public: /// A queue used for performing data recursion over statements. /// Parameters involving this type are used to implement data /// recursion over Stmts and Exprs within this class, and should /// typically not be explicitly specified by derived classes. - typedef SmallVectorImpl DataRecursionQueue; + /// The bool bit indicates whether the statement has been traversed or not. + typedef SmallVectorImpl> + DataRecursionQueue; /// \brief Return a reference to the derived class. Derived &getDerived() { return *static_cast(this); } @@ -156,6 +162,9 @@ template class RecursiveASTVisitor { /// code, e.g., implicit constructors and destructors. bool shouldVisitImplicitCode() const { return false; } + /// \brief Return whether this visitor should traverse post-order. + bool shouldTraversePostOrder() const { return false; } + /// \brief Recursively visit a statement or expression, by /// dispatching to Traverse*() based on the argument's dynamic type. /// @@ -163,6 +172,18 @@ template class RecursiveASTVisitor { /// otherwise (including when the argument is nullptr). bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr); + /// Invoked before visiting a statement or expression via data recursion. + /// + /// \returns false to skip visiting the node, true otherwise. + bool dataTraverseStmtPre(Stmt *S) { return true; } + + /// Invoked after visiting a statement or expression via data recursion. + /// This is not invoked if the previously invoked \c dataTraverseStmtPre + /// returned false. + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool dataTraverseStmtPost(Stmt *S) { return true; } + /// \brief Recursively visit a type, by dispatching to /// Traverse*Type() based on the argument's getTypeClass() property. /// @@ -335,7 +356,7 @@ template class RecursiveASTVisitor { bool TraverseUnary##NAME(UnaryOperator *S, \ DataRecursionQueue *Queue = nullptr) { \ TRY_TO(WalkUpFromUnary##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \ return true; \ } \ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ @@ -353,9 +374,10 @@ template class RecursiveASTVisitor { // (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) { \ - TRY_TO(WalkUpFromBin##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \ + 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) { \ @@ -480,8 +502,12 @@ template class RecursiveASTVisitor { #include "clang/Basic/OpenMPKinds.def" /// \brief Process clauses with list of variables. template bool VisitOMPClauseList(T *Node); + /// Process clauses with pre-initis. + bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node); + bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node); bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue); + bool PostVisitStmt(Stmt *S); }; template @@ -539,6 +565,24 @@ bool RecursiveASTVisitor::dataTraverseNode(Stmt *S, #undef DISPATCH_STMT + +template +bool RecursiveASTVisitor::PostVisitStmt(Stmt *S) { + 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; +#include "clang/AST/StmtNodes.inc" + } + + return true; +} + +#undef DISPATCH_STMT + template bool RecursiveASTVisitor::TraverseStmt(Stmt *S, DataRecursionQueue *Queue) { @@ -546,20 +590,35 @@ bool RecursiveASTVisitor::TraverseStmt(Stmt *S, return true; if (Queue) { - Queue->push_back(S); + Queue->push_back({S, false}); return true; } - SmallVector LocalQueue; - LocalQueue.push_back(S); + SmallVector, 8> LocalQueue; + LocalQueue.push_back({S, false}); while (!LocalQueue.empty()) { - Stmt *CurrS = LocalQueue.pop_back_val(); + auto &CurrSAndVisited = LocalQueue.back(); + Stmt *CurrS = CurrSAndVisited.getPointer(); + bool Visited = CurrSAndVisited.getInt(); + if (Visited) { + LocalQueue.pop_back(); + TRY_TO(dataTraverseStmtPost(CurrS)); + if (getDerived().shouldTraversePostOrder()) { + TRY_TO(PostVisitStmt(CurrS)); + } + continue; + } - size_t N = LocalQueue.size(); - TRY_TO(dataTraverseNode(CurrS, &LocalQueue)); - // Process new children in the order they were added. - std::reverse(LocalQueue.begin() + N, LocalQueue.end()); + if (getDerived().dataTraverseStmtPre(CurrS)) { + CurrSAndVisited.setInt(true); + size_t N = LocalQueue.size(); + TRY_TO(dataTraverseNode(CurrS, &LocalQueue)); + // Process new children in the order they were added. + std::reverse(LocalQueue.begin() + N, LocalQueue.end()); + } else { + LocalQueue.pop_back(); + } } return true; @@ -809,6 +868,17 @@ bool RecursiveASTVisitor::TraverseConstructorInitializer( if (Init->isWritten() || getDerived().shouldVisitImplicitCode()) TRY_TO(TraverseStmt(Init->getInit())); + + if (getDerived().shouldVisitImplicitCode()) + // The braces for this one-line loop are required for MSVC2013. It + // refuses to compile + // for (int i : int_vec) + // do {} while(false); + // without braces on the for loop. + for (VarDecl *VD : Init->getArrayIndices()) { + TRY_TO(TraverseDecl(VD)); + } + return true; } @@ -834,8 +904,11 @@ bool RecursiveASTVisitor::TraverseLambdaBody( #define DEF_TRAVERSE_TYPE(TYPE, CODE) \ template \ bool RecursiveASTVisitor::Traverse##TYPE(TYPE *T) { \ - TRY_TO(WalkUpFrom##TYPE(T)); \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##TYPE(T)); \ { CODE; } \ + if (getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##TYPE(T)); \ return true; \ } @@ -1238,10 +1311,16 @@ bool RecursiveASTVisitor::TraverseDeclContextHelper(DeclContext *DC) { #define DEF_TRAVERSE_DECL(DECL, CODE) \ template \ bool RecursiveASTVisitor::Traverse##DECL(DECL *D) { \ - TRY_TO(WalkUpFrom##DECL(D)); \ + bool ShouldVisitChildren = true; \ + bool ReturnValue = true; \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##DECL(D)); \ { CODE; } \ - TRY_TO(TraverseDeclContextHelper(dyn_cast(D))); \ - return true; \ + if (ReturnValue && ShouldVisitChildren) \ + TRY_TO(TraverseDeclContextHelper(dyn_cast(D))); \ + if (ReturnValue && getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##DECL(D)); \ + return ReturnValue; \ } DEF_TRAVERSE_DECL(AccessSpecDecl, {}) @@ -1255,18 +1334,12 @@ DEF_TRAVERSE_DECL(BlockDecl, { TRY_TO(TraverseStmt(I.getCopyExpr())); } } - // This return statement makes sure the traversal of nodes in - // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) - // is skipped - don't remove it. - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(CapturedDecl, { TRY_TO(TraverseStmt(D->getBody())); - // This return statement makes sure the traversal of nodes in - // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) - // is skipped - don't remove it. - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(EmptyDecl, {}) @@ -1325,6 +1398,10 @@ DEF_TRAVERSE_DECL( // D->getAnonymousNamespace(). }) +DEF_TRAVERSE_DECL(PragmaCommentDecl, {}) + +DEF_TRAVERSE_DECL(PragmaDetectMismatchDecl, {}) + DEF_TRAVERSE_DECL(ExternCContextDecl, {}) DEF_TRAVERSE_DECL(NamespaceAliasDecl, { @@ -1332,11 +1409,7 @@ DEF_TRAVERSE_DECL(NamespaceAliasDecl, { // We shouldn't traverse an aliased namespace, since it will be // defined (and, therefore, traversed) somewhere else. - // - // This return statement makes sure the traversal of nodes in - // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) - // is skipped - don't remove it. - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl. @@ -1385,14 +1458,13 @@ DEF_TRAVERSE_DECL(ObjCMethodDecl, { if (D->getReturnTypeSourceInfo()) { TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc())); } - for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); + for (ParmVarDecl *Parameter : D->parameters()) { + TRY_TO(TraverseDecl(Parameter)); } if (D->isThisDeclarationADefinition()) { TRY_TO(TraverseStmt(D->getBody())); } - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { @@ -1409,7 +1481,7 @@ DEF_TRAVERSE_DECL(ObjCPropertyDecl, { TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); else TRY_TO(TraverseType(D->getType())); - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(UsingDecl, { @@ -1423,12 +1495,24 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, { DEF_TRAVERSE_DECL(UsingShadowDecl, {}) +DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {}) + DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { for (auto *I : D->varlists()) { TRY_TO(TraverseStmt(I)); } }) +DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, { + TRY_TO(TraverseStmt(D->getCombiner())); + if (auto *Initializer = D->getInitializer()) + TRY_TO(TraverseStmt(Initializer)); + TRY_TO(TraverseType(D->getType())); + return true; +}) + +DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); }) + // A helper method for TemplateDecl's children. template bool RecursiveASTVisitor::TraverseTemplateParameterListHelper( @@ -1778,10 +1862,9 @@ bool RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) { // if the traverser is visiting implicit code. Parameter variable // declarations do not have valid TypeSourceInfo, so to visit them // we need to traverse the declarations explicitly. - for (FunctionDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); - I != E; ++I) - TRY_TO(TraverseDecl(*I)); + for (ParmVarDecl *Parameter : D->parameters()) { + TRY_TO(TraverseDecl(Parameter)); + } } if (CXXConstructorDecl *Ctor = dyn_cast(D)) { @@ -1800,19 +1883,22 @@ bool RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) { DEF_TRAVERSE_DECL(FunctionDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) DEF_TRAVERSE_DECL(CXXMethodDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) DEF_TRAVERSE_DECL(CXXConstructorDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) // CXXConversionDecl is the declaration of a type conversion operator. @@ -1820,13 +1906,15 @@ DEF_TRAVERSE_DECL(CXXConstructorDecl, { DEF_TRAVERSE_DECL(CXXConversionDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) DEF_TRAVERSE_DECL(CXXDestructorDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) template @@ -1878,12 +1966,19 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { template \ bool RecursiveASTVisitor::Traverse##STMT( \ STMT *S, DataRecursionQueue *Queue) { \ - TRY_TO(WalkUpFrom##STMT(S)); \ + bool ShouldVisitChildren = true; \ + bool ReturnValue = true; \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##STMT(S)); \ { CODE; } \ - for (Stmt *SubStmt : S->children()) { \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ + if (ShouldVisitChildren) { \ + for (Stmt *SubStmt : S->children()) { \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ + } \ } \ - return true; \ + if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##STMT(S)); \ + return ReturnValue; \ } DEF_TRAVERSE_STMT(GCCAsmStmt, { @@ -1920,7 +2015,7 @@ DEF_TRAVERSE_STMT(DeclStmt, { // initializer]'. The decls above already traverse over the // initializers, so we don't have to do it again (which // children() would do). - return true; + ShouldVisitChildren = false; }) // These non-expr stmts (most of them), do not need any action except @@ -1952,7 +2047,7 @@ DEF_TRAVERSE_STMT(CXXForRangeStmt, { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit()); TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody()); // Visit everything else only if shouldVisitImplicitCode(). - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(MSDependentExistsStmt, { @@ -2029,7 +2124,11 @@ template bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr( InitListExpr *S, DataRecursionQueue *Queue) { if (S) { - TRY_TO(WalkUpFromInitListExpr(S)); + // Skip this if we traverse postorder. We will visit it later + // in PostVisitStmt. + if (!getDerived().shouldTraversePostOrder()) + TRY_TO(WalkUpFromInitListExpr(S)); + // All we need are the default actions. FIXME: use a helper function. for (Stmt *SubStmt : S->children()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); @@ -2049,7 +2148,7 @@ DEF_TRAVERSE_STMT(InitListExpr, { S->isSemanticForm() ? S->getSyntacticForm() : S, Queue)); TRY_TO(TraverseSynOrSemInitListExpr( S->isSemanticForm() ? S : S->getSemanticForm(), Queue)); - return true; + ShouldVisitChildren = false; }) // GenericSelectionExpr is a special case because the types and expressions @@ -2062,7 +2161,7 @@ DEF_TRAVERSE_STMT(GenericSelectionExpr, { TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i)); } - return true; + ShouldVisitChildren = false; }) // PseudoObjectExpr is a special case because of the weirdness with @@ -2077,7 +2176,7 @@ DEF_TRAVERSE_STMT(PseudoObjectExpr, { sub = OVE->getSourceExpr(); TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub); } - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { @@ -2181,7 +2280,8 @@ DEF_TRAVERSE_STMT(LambdaExpr, { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE); } - return TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue); + ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue); + ShouldVisitChildren = false; }) DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { @@ -2214,6 +2314,7 @@ DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {}) DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {}) DEF_TRAVERSE_STMT(CXXDeleteExpr, {}) DEF_TRAVERSE_STMT(ExprWithCleanups, {}) +DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {}) DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {}) DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {}) DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { @@ -2251,6 +2352,7 @@ DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {}) DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {}) DEF_TRAVERSE_STMT(ParenExpr, {}) DEF_TRAVERSE_STMT(ParenListExpr, {}) DEF_TRAVERSE_STMT(PredefinedExpr, {}) @@ -2307,25 +2409,25 @@ DEF_TRAVERSE_STMT(AtomicExpr, {}) DEF_TRAVERSE_STMT(CoroutineBodyStmt, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody()); - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(CoreturnStmt, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(CoawaitExpr, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(CoyieldExpr, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); - return true; + ShouldVisitChildren = false; } }) @@ -2433,9 +2535,24 @@ DEF_TRAVERSE_STMT(OMPTargetDirective, DEF_TRAVERSE_STMT(OMPTargetDataDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetExitDataDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetParallelDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetParallelForDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPTeamsDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTargetUpdateDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPTaskLoopDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) @@ -2445,6 +2562,18 @@ DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective, DEF_TRAVERSE_STMT(OMPDistributeDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPDistributeSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { @@ -2457,12 +2586,28 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { break; #include "clang/Basic/OpenMPKinds.def" case OMPC_threadprivate: + case OMPC_uniform: case OMPC_unknown: break; } return true; } +template +bool RecursiveASTVisitor::VisitOMPClauseWithPreInit( + OMPClauseWithPreInit *Node) { + TRY_TO(TraverseStmt(Node->getPreInitStmt())); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPClauseWithPostUpdate( + OMPClauseWithPostUpdate *Node) { + TRY_TO(VisitOMPClauseWithPreInit(Node)); + TRY_TO(TraverseStmt(Node->getPostUpdateExpr())); + return true; +} + template bool RecursiveASTVisitor::VisitOMPIfClause(OMPIfClause *C) { TRY_TO(TraverseStmt(C->getCondition())); @@ -2514,8 +2659,8 @@ bool RecursiveASTVisitor::VisitOMPProcBindClause(OMPProcBindClause *) { template bool RecursiveASTVisitor::VisitOMPScheduleClause(OMPScheduleClause *C) { + TRY_TO(VisitOMPClauseWithPreInit(C)); TRY_TO(TraverseStmt(C->getChunkSize())); - TRY_TO(TraverseStmt(C->getHelperChunkSize())); return true; } @@ -2603,6 +2748,7 @@ template bool RecursiveASTVisitor::VisitOMPFirstprivateClause( OMPFirstprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPreInit(C)); for (auto *E : C->private_copies()) { TRY_TO(TraverseStmt(E)); } @@ -2616,6 +2762,7 @@ template bool RecursiveASTVisitor::VisitOMPLastprivateClause( OMPLastprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->private_copies()) { TRY_TO(TraverseStmt(E)); } @@ -2642,6 +2789,7 @@ bool RecursiveASTVisitor::VisitOMPLinearClause(OMPLinearClause *C) { TRY_TO(TraverseStmt(C->getStep())); TRY_TO(TraverseStmt(C->getCalcStep())); TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->privates()) { TRY_TO(TraverseStmt(E)); } @@ -2701,6 +2849,7 @@ RecursiveASTVisitor::VisitOMPReductionClause(OMPReductionClause *C) { TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->privates()) { TRY_TO(TraverseStmt(E)); } @@ -2781,6 +2930,46 @@ bool RecursiveASTVisitor::VisitOMPHintClause(OMPHintClause *C) { return true; } +template +bool RecursiveASTVisitor::VisitOMPDistScheduleClause( + OMPDistScheduleClause *C) { + TRY_TO(VisitOMPClauseWithPreInit(C)); + TRY_TO(TraverseStmt(C->getChunkSize())); + return true; +} + +template +bool +RecursiveASTVisitor::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) { + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPToClause(OMPToClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPFromClause(OMPFromClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPUseDevicePtrClause( + OMPUseDevicePtrClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPIsDevicePtrClause( + OMPIsDevicePtrClause *C) { + TRY_TO(VisitOMPClauseList(C)); + 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/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index d3950e92cf0..96847cf88f9 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -93,6 +93,13 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt { unsigned NumStmts : 32 - NumStmtBits; }; + class IfStmtBitfields { + friend class IfStmt; + unsigned : NumStmtBits; + + unsigned IsConstexpr : 1; + }; + class ExprBitfields { friend class Expr; friend class DeclRefExpr; // computeDependence @@ -115,6 +122,7 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt { friend class OverloadExpr; // ctor friend class PseudoObjectExpr; // ctor friend class AtomicExpr; // ctor + friend class OpaqueValueExpr; // ctor unsigned : NumStmtBits; unsigned ValueKind : 2; @@ -191,7 +199,10 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt { unsigned : NumExprBits; - unsigned NumObjects : 32 - NumExprBits; + // When false, it must not have side effects. + unsigned CleanupsHaveSideEffects : 1; + + unsigned NumObjects : 32 - 1 - NumExprBits; }; class PseudoObjectExprBitfields { @@ -244,6 +255,7 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt { union { StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; + IfStmtBitfields IfStmtBits; ExprBitfields ExprBits; CharacterLiteralBitfields CharacterLiteralBits; FloatingLiteralBitfields FloatingLiteralBits; @@ -867,14 +879,15 @@ class AttributedStmt : public Stmt { /// IfStmt - This represents an if/then/else. /// class IfStmt : public Stmt { - enum { VAR, COND, THEN, ELSE, END_EXPR }; + enum { INIT, VAR, COND, THEN, ELSE, END_EXPR }; Stmt* SubExprs[END_EXPR]; SourceLocation IfLoc; SourceLocation ElseLoc; public: - IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, + IfStmt(const ASTContext &C, SourceLocation IL, + bool IsConstexpr, Stmt *init, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = nullptr); @@ -898,6 +911,9 @@ class IfStmt : public Stmt { return reinterpret_cast(SubExprs[VAR]); } + Stmt *getInit() { return SubExprs[INIT]; } + const Stmt *getInit() const { return SubExprs[INIT]; } + void setInit(Stmt *S) { SubExprs[INIT] = S; } const Expr *getCond() const { return reinterpret_cast(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast(E); } const Stmt *getThen() const { return SubExprs[THEN]; } @@ -914,6 +930,9 @@ class IfStmt : public Stmt { SourceLocation getElseLoc() const { return ElseLoc; } void setElseLoc(SourceLocation L) { ElseLoc = L; } + bool isConstexpr() const { return IfStmtBits.IsConstexpr; } + void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; } + SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; } SourceLocation getLocEnd() const LLVM_READONLY { if (SubExprs[ELSE]) @@ -937,7 +956,7 @@ class IfStmt : public Stmt { /// class SwitchStmt : public Stmt { SourceLocation SwitchLoc; - enum { VAR, COND, BODY, END_EXPR }; + enum { INIT, VAR, COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; // This points to a linked list of case and default statements and, if the // SwitchStmt is a switch on an enum value, records whether all the enum @@ -946,7 +965,7 @@ class SwitchStmt : public Stmt { llvm::PointerIntPair FirstCase; public: - SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); + SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond); /// \brief Build a empty switch statement. explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } @@ -969,6 +988,9 @@ class SwitchStmt : public Stmt { return reinterpret_cast(SubExprs[VAR]); } + Stmt *getInit() { return SubExprs[INIT]; } + const Stmt *getInit() const { return SubExprs[INIT]; } + void setInit(Stmt *S) { SubExprs[INIT] = S; } const Expr *getCond() const { return reinterpret_cast(SubExprs[COND]);} const Stmt *getBody() const { return SubExprs[BODY]; } const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); } diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 1ca73e207e4..1d29c228a4b 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -127,7 +127,7 @@ class CXXTryStmt : public Stmt { /// can be extracted using getLoopVariable and getRangeInit. class CXXForRangeStmt : public Stmt { SourceLocation ForLoc; - enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; + enum { RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END }; // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; @@ -137,7 +137,7 @@ class CXXForRangeStmt : public Stmt { friend class ASTStmtReader; public: - CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, + CXXForRangeStmt(DeclStmt *Range, DeclStmt *Begin, DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, SourceLocation FL, SourceLocation CAL, SourceLocation CL, SourceLocation RPL); @@ -152,9 +152,10 @@ class CXXForRangeStmt : public Stmt { DeclStmt *getRangeStmt() { return cast(SubExprs[RANGE]); } - DeclStmt *getBeginEndStmt() { - return cast_or_null(SubExprs[BEGINEND]); + DeclStmt *getBeginStmt() { + return cast_or_null(SubExprs[BEGINSTMT]); } + DeclStmt *getEndStmt() { return cast_or_null(SubExprs[ENDSTMT]); } Expr *getCond() { return cast_or_null(SubExprs[COND]); } Expr *getInc() { return cast_or_null(SubExprs[INC]); } DeclStmt *getLoopVarStmt() { return cast(SubExprs[LOOPVAR]); } @@ -163,8 +164,11 @@ class CXXForRangeStmt : public Stmt { const DeclStmt *getRangeStmt() const { return cast(SubExprs[RANGE]); } - const DeclStmt *getBeginEndStmt() const { - return cast_or_null(SubExprs[BEGINEND]); + const DeclStmt *getBeginStmt() const { + return cast_or_null(SubExprs[BEGINSTMT]); + } + const DeclStmt *getEndStmt() const { + return cast_or_null(SubExprs[ENDSTMT]); } const Expr *getCond() const { return cast_or_null(SubExprs[COND]); @@ -179,7 +183,8 @@ class CXXForRangeStmt : public Stmt { void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast(E); } void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } - void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } + void setBeginStmt(Stmt *S) { SubExprs[BEGINSTMT] = S; } + void setEndStmt(Stmt *S) { SubExprs[ENDSTMT] = S; } void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast(E); } void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast(E); } void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index 68fe3ef697b..5260b6985bf 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -326,7 +326,7 @@ class ObjCAtThrowStmt : public Stmt { Expr *getThrowExpr() { return reinterpret_cast(Throw); } void setThrowExpr(Stmt *S) { Throw = S; } - SourceLocation getThrowLoc() { return AtThrowLoc; } + SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; } void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; } SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; } diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index 1ba859c0b84..1e357263461 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -70,8 +70,7 @@ class OMPExecutableDirective : public Stmt { : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), EndLoc(std::move(EndLoc)), NumClauses(NumClauses), NumChildren(NumChildren), - ClausesOffset(llvm::RoundUpToAlignment(sizeof(T), - llvm::alignOf())) {} + ClausesOffset(llvm::alignTo(sizeof(T), llvm::alignOf())) {} /// \brief Sets the list of variables for this clause. /// @@ -300,9 +299,11 @@ class OMPLoopDirective : public OMPExecutableDirective { /// This enumeration contains offsets to all the pointers to children /// expressions stored in OMPLoopDirective. /// The first 9 children are nesessary for all the loop directives, and - /// the next 7 are specific to the worksharing ones. + /// the next 10 are specific to the worksharing ones. /// After the fixed children, three arrays of length CollapsedNum are /// allocated: loop counters, their updates and final values. + /// PrevLowerBound and PrevUpperBound are used to communicate blocking + /// information in composite constructs which require loop blocking /// enum { AssociatedStmtOffset = 0, @@ -313,21 +314,25 @@ class OMPLoopDirective : public OMPExecutableDirective { CondOffset = 5, InitOffset = 6, IncOffset = 7, + PreInitsOffset = 8, // The '...End' enumerators do not correspond to child expressions - they // specify the offset to the end (and start of the following counters/ // updates/finals arrays). - DefaultEnd = 8, + DefaultEnd = 9, // The following 7 exprs are used by worksharing loops only. - IsLastIterVariableOffset = 8, - LowerBoundVariableOffset = 9, - UpperBoundVariableOffset = 10, - StrideVariableOffset = 11, - EnsureUpperBoundOffset = 12, - NextLowerBoundOffset = 13, - NextUpperBoundOffset = 14, + IsLastIterVariableOffset = 9, + LowerBoundVariableOffset = 10, + UpperBoundVariableOffset = 11, + StrideVariableOffset = 12, + EnsureUpperBoundOffset = 13, + NextLowerBoundOffset = 14, + NextUpperBoundOffset = 15, + NumIterationsOffset = 16, + PrevLowerBoundVariableOffset = 17, + PrevUpperBoundVariableOffset = 18, // Offset to the end (and start of the following counters/updates/finals // arrays) for worksharing loop directives. - WorksharingEnd = 15, + WorksharingEnd = 19, }; /// \brief Get the counters storage. @@ -423,6 +428,9 @@ class OMPLoopDirective : public OMPExecutableDirective { } void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } + void setPreInits(Stmt *PreInits) { + *std::next(child_begin(), PreInitsOffset) = PreInits; + } void setIsLastIterVariable(Expr *IL) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || @@ -472,6 +480,27 @@ class OMPLoopDirective : public OMPExecutableDirective { "expected worksharing loop directive"); *std::next(child_begin(), NextUpperBoundOffset) = NUB; } + void setNumIterations(Expr *NI) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), NumIterationsOffset) = NI; + } + void setPrevLowerBoundVariable(Expr *PrevLB) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB; + } + void setPrevUpperBoundVariable(Expr *PrevUB) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB; + } void setCounters(ArrayRef A); void setPrivateCounters(ArrayRef A); void setInits(ArrayRef A); @@ -512,6 +541,12 @@ class OMPLoopDirective : public OMPExecutableDirective { Expr *NLB; /// \brief Update of UpperBound for statically sheduled 'omp for' loops. Expr *NUB; + /// \brief PreviousLowerBound - local variable passed to runtime in the + /// enclosing schedule or null if that does not apply. + Expr *PrevLB; + /// \brief PreviousUpperBound - local variable passed to runtime in the + /// enclosing schedule or null if that does not apply. + Expr *PrevUB; /// \brief Counters Loop counters. SmallVector Counters; /// \brief PrivateCounters Loop counters. @@ -522,6 +557,8 @@ class OMPLoopDirective : public OMPExecutableDirective { SmallVector Updates; /// \brief Final loop counter values for GodeGen. SmallVector Finals; + /// Init statement for all captured expressions. + Stmt *PreInits; /// \brief Check if all the expressions are built (does not check the /// worksharing ones). @@ -548,6 +585,9 @@ class OMPLoopDirective : public OMPExecutableDirective { EUB = nullptr; NLB = nullptr; NUB = nullptr; + NumIterations = nullptr; + PrevLB = nullptr; + PrevUB = nullptr; Counters.resize(Size); PrivateCounters.resize(Size); Inits.resize(Size); @@ -560,6 +600,7 @@ class OMPLoopDirective : public OMPExecutableDirective { Updates[i] = nullptr; Finals[i] = nullptr; } + PreInits = nullptr; } }; @@ -594,55 +635,90 @@ class OMPLoopDirective : public OMPExecutableDirective { return const_cast( reinterpret_cast(*std::next(child_begin(), IncOffset))); } + const Stmt *getPreInits() const { + return *std::next(child_begin(), PreInitsOffset); + } + Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); } Expr *getIsLastIterVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), IsLastIterVariableOffset))); } Expr *getLowerBoundVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), LowerBoundVariableOffset))); } Expr *getUpperBoundVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), UpperBoundVariableOffset))); } Expr *getStrideVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), StrideVariableOffset))); } Expr *getEnsureUpperBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), EnsureUpperBoundOffset))); } Expr *getNextLowerBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), NextLowerBoundOffset))); } Expr *getNextUpperBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast(reinterpret_cast( *std::next(child_begin(), NextUpperBoundOffset))); } + Expr *getNumIterations() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast(reinterpret_cast( + *std::next(child_begin(), NumIterationsOffset))); + } + Expr *getPrevLowerBoundVariable() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast(reinterpret_cast( + *std::next(child_begin(), PrevLowerBoundVariableOffset))); + } + Expr *getPrevUpperBoundVariable() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast(reinterpret_cast( + *std::next(child_begin(), PrevUpperBoundVariableOffset))); + } const Stmt *getBody() const { // This relies on the loop form is already checked by Sema. Stmt *Body = getAssociatedStmt()->IgnoreContainers(true); @@ -692,7 +768,12 @@ class OMPLoopDirective : public OMPExecutableDirective { T->getStmtClass() == OMPParallelForSimdDirectiveClass || T->getStmtClass() == OMPTaskLoopDirectiveClass || T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || - T->getStmtClass() == OMPDistributeDirectiveClass; + T->getStmtClass() == OMPDistributeDirectiveClass || + T->getStmtClass() == OMPTargetParallelForDirectiveClass || + T->getStmtClass() == OMPDistributeParallelForDirectiveClass || + T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || + T->getStmtClass() == OMPDistributeSimdDirectiveClass || + T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; } }; @@ -2039,6 +2120,264 @@ class OMPTargetDataDirective : public OMPExecutableDirective { } }; +/// \brief This represents '#pragma omp target enter data' directive. +/// +/// \code +/// #pragma omp target enter data device(0) if(a) map(b[:]) +/// \endcode +/// In this example directive '#pragma omp target enter data' has clauses +/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array +/// section 'b[:]'. +/// +class OMPTargetEnterDataDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief 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 The number of clauses. + /// + OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, + OMPD_target_enter_data, StartLoc, EndLoc, + NumClauses, /*NumChildren=*/0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetEnterDataDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, + OMPD_target_enter_data, SourceLocation(), + SourceLocation(), NumClauses, + /*NumChildren=*/0) {} + +public: + /// \brief 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 OMPTargetEnterDataDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, + unsigned N, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp target exit data' directive. +/// +/// \code +/// #pragma omp target exit data device(0) if(a) map(b[:]) +/// \endcode +/// In this example directive '#pragma omp target exit data' has clauses +/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array +/// section 'b[:]'. +/// +class OMPTargetExitDataDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief 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 The number of clauses. + /// + OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, + OMPD_target_exit_data, StartLoc, EndLoc, + NumClauses, /*NumChildren=*/0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetExitDataDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, + OMPD_target_exit_data, SourceLocation(), + SourceLocation(), NumClauses, + /*NumChildren=*/0) {} + +public: + /// \brief 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 OMPTargetExitDataDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, + unsigned N, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetExitDataDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp target parallel' directive. +/// +/// \code +/// #pragma omp target parallel if(a) +/// \endcode +/// In this example directive '#pragma omp target parallel' has clause 'if' with +/// condition 'a'. +/// +class OMPTargetParallelDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief 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. + /// + OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, + OMPD_target_parallel, StartLoc, EndLoc, + NumClauses, /*NumChildren=*/1) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetParallelDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, + OMPD_target_parallel, SourceLocation(), + SourceLocation(), NumClauses, + /*NumChildren=*/1) {} + +public: + /// \brief 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. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPTargetParallelDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPTargetParallelDirective * + CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetParallelDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp target parallel for' directive. +/// +/// \code +/// #pragma omp target parallel for private(a,b) reduction(+:c,d) +/// \endcode +/// In this example directive '#pragma omp target parallel for' has clauses +/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' +/// and variables 'c' and 'd'. +/// +class OMPTargetParallelForDirective : public OMPLoopDirective { + friend class ASTStmtReader; + + /// \brief true if current region has inner cancel directive. + bool HasCancel; + + /// \brief 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 CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, + OMPD_target_parallel_for, StartLoc, EndLoc, + CollapsedNum, NumClauses), + HasCancel(false) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetParallelForDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, + OMPD_target_parallel_for, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } + +public: + /// \brief 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 CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// \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); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetParallelForDirectiveClass; + } +}; + /// \brief This represents '#pragma omp teams' directive. /// /// \code @@ -2395,7 +2734,7 @@ class OMPDistributeDirective : public OMPLoopDirective { /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. - /// + /// static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, @@ -2417,6 +2756,340 @@ class OMPDistributeDirective : public OMPLoopDirective { } }; +/// \brief This represents '#pragma omp target update' directive. +/// +/// \code +/// #pragma omp target update to(a) from(b) device(1) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'to' with +/// argument 'a', clause 'from' with argument 'b' and clause 'device' with +/// argument '1'. +/// +class OMPTargetUpdateDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief 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 The number of clauses. + /// + OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, + OMPD_target_update, StartLoc, EndLoc, NumClauses, + 0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetUpdateDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, + OMPD_target_update, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// \brief 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 OMPTargetUpdateDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses The number of clauses. + /// + static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetUpdateDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp distribute parallel for' composite +/// directive. +/// +/// \code +/// #pragma omp distribute parallel for private(a,b) +/// \endcode +/// In this example directive '#pragma omp distribute parallel for' has clause +/// 'private' with the variables 'a' and 'b' +/// +class OMPDistributeParallelForDirective : public OMPLoopDirective { + friend class ASTStmtReader; + + /// \brief 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 CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeParallelForDirective(SourceLocation StartLoc, + SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, + OMPD_distribute_parallel_for, StartLoc, EndLoc, + CollapsedNum, NumClauses) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeParallelForDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, + OMPD_distribute_parallel_for, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// \brief 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 CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeParallelForDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; + } +}; + +/// This represents '#pragma omp distribute parallel for simd' composite +/// directive. +/// +/// \code +/// #pragma omp distribute parallel for simd private(x) +/// \endcode +/// In this example directive '#pragma omp distribute parallel for simd' has +/// clause 'private' with the variables 'x' +/// +class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { + 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 CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, + SourceLocation EndLoc, + unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, + OMPD_distribute_parallel_for_simd, StartLoc, + EndLoc, CollapsedNum, NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, + OMPD_distribute_parallel_for_simd, + SourceLocation(), SourceLocation(), CollapsedNum, + NumClauses) {} + +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 CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeParallelForSimdDirective *Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeParallelForSimdDirective *CreateEmpty( + const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; + } +}; + +/// This represents '#pragma omp distribute simd' composite directive. +/// +/// \code +/// #pragma omp distribute simd private(x) +/// \endcode +/// In this example directive '#pragma omp distribute simd' has clause +/// 'private' with the variables 'x' +/// +class OMPDistributeSimdDirective final : public OMPLoopDirective { + 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 CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, + OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum, + NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, + OMPD_distribute_simd, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +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 CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeSimdDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeSimdDirectiveClass; + } +}; + +/// This represents '#pragma omp target parallel for simd' directive. +/// +/// \code +/// #pragma omp target parallel for simd private(a) map(b) safelen(c) +/// \endcode +/// In this example directive '#pragma omp target parallel for simd' has clauses +/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' +/// with the variable 'c'. +/// +class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { + 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 CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, + OMPD_target_parallel_for_simd, StartLoc, EndLoc, + CollapsedNum, NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, + OMPD_target_parallel_for_simd, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +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 CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPTargetParallelForSimdDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index f87171a81d1..b9c2c08943e 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -354,6 +354,12 @@ class TemplateArgument { /// \brief Print this template argument to the given output stream. void print(const PrintingPolicy &Policy, raw_ostream &Out) const; + /// \brief Debugging aid that dumps the template argument. + void dump(raw_ostream &Out) const; + + /// \brief Debugging aid that dumps the template argument to standard error. + void dump() const; + /// \brief Used to insert TemplateArguments into FoldingSets. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; }; diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 3e10d2fc4ad..bf4d008ee80 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H +#include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index d63b2c43d55..1067c086c76 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -111,6 +111,7 @@ namespace clang { /// The collection of all-type qualifiers we support. /// Clang supports five independent qualifiers: /// * C99: const, volatile, and restrict +/// * MS: __unaligned /// * Embedded C (TR18037): address spaces /// * Objective C: the GC attributes (none, weak, or strong) class Qualifiers { @@ -152,8 +153,8 @@ class Qualifiers { enum { /// The maximum supported address space number. - /// 24 bits should be enough for anyone. - MaxAddressSpace = 0xffffffu, + /// 23 bits should be enough for anyone. + MaxAddressSpace = 0x7fffffu, /// The width of the "fast" qualifier mask. FastWidth = 3, @@ -214,6 +215,12 @@ class Qualifiers { return Qs; } + static Qualifiers fromCVRUMask(unsigned CVRU) { + Qualifiers Qs; + Qs.addCVRUQualifiers(CVRU); + return Qs; + } + // Deserialize qualifiers from an opaque representation. static Qualifiers fromOpaqueValue(unsigned opaque) { Qualifiers Qs; @@ -264,6 +271,17 @@ class Qualifiers { assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); Mask |= mask; } + void addCVRUQualifiers(unsigned mask) { + assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits"); + Mask |= mask; + } + + bool hasUnaligned() const { return Mask & UMask; } + void setUnaligned(bool flag) { + Mask = (Mask & ~UMask) | (flag ? UMask : 0); + } + void removeUnaligned() { Mask &= ~UMask; } + void addUnaligned() { Mask |= UMask; } bool hasObjCGCAttr() const { return Mask & GCAttrMask; } GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } @@ -433,7 +451,9 @@ class Qualifiers { // ObjC lifetime qualifiers must match exactly. getObjCLifetime() == other.getObjCLifetime() && // CVR qualifiers may subset. - (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); + (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) && + // U qualifier may superset. + (!other.hasUnaligned() || hasUnaligned()); } /// \brief Determines if these qualifiers compatibly include another set of @@ -501,16 +521,19 @@ class Qualifiers { private: - // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31| - // |C R V|GCAttr|Lifetime|AddressSpace| + // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| + // |C R V|U|GCAttr|Lifetime|AddressSpace| uint32_t Mask; - static const uint32_t GCAttrMask = 0x18; - static const uint32_t GCAttrShift = 3; - static const uint32_t LifetimeMask = 0xE0; - static const uint32_t LifetimeShift = 5; - static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask); - static const uint32_t AddressSpaceShift = 8; + static const uint32_t UMask = 0x8; + static const uint32_t UShift = 3; + static const uint32_t GCAttrMask = 0x30; + static const uint32_t GCAttrShift = 4; + static const uint32_t LifetimeMask = 0x1C0; + static const uint32_t LifetimeShift = 6; + static const uint32_t AddressSpaceMask = + ~(CVRMask | UMask | GCAttrMask | LifetimeMask); + static const uint32_t AddressSpaceShift = 9; }; /// A std::pair-like structure for storing a qualified type split @@ -709,27 +732,27 @@ class QualType { /// applied to this type. unsigned getCVRQualifiers() const; - bool isConstant(ASTContext& Ctx) const { + bool isConstant(const ASTContext& Ctx) const { return QualType::isConstant(*this, Ctx); } /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). - bool isPODType(ASTContext &Context) const; + bool isPODType(const ASTContext &Context) const; /// Return true if this is a POD type according to the rules of the C++98 /// standard, regardless of the current compilation's language. - bool isCXX98PODType(ASTContext &Context) const; + bool isCXX98PODType(const ASTContext &Context) const; /// Return true if this is a POD type according to the more relaxed rules /// of the C++11 standard, regardless of the current compilation's language. /// (C++0x [basic.types]p9) - bool isCXX11PODType(ASTContext &Context) const; + bool isCXX11PODType(const ASTContext &Context) const; /// Return true if this is a trivial type per (C++0x [basic.types]p9) - bool isTrivialType(ASTContext &Context) const; + bool isTrivialType(const ASTContext &Context) const; /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) - bool isTriviallyCopyableType(ASTContext &Context) const; + bool isTriviallyCopyableType(const ASTContext &Context) const; // Don't promise in the API that anything besides 'const' can be // easily added. @@ -909,16 +932,19 @@ class QualType { std::string getAsString(const PrintingPolicy &Policy) const; void print(raw_ostream &OS, const PrintingPolicy &Policy, - const Twine &PlaceHolder = Twine()) const { - print(split(), OS, Policy, PlaceHolder); + const Twine &PlaceHolder = Twine(), + unsigned Indentation = 0) const { + print(split(), OS, Policy, PlaceHolder, Indentation); } static void print(SplitQualType split, raw_ostream &OS, - const PrintingPolicy &policy, const Twine &PlaceHolder) { - return print(split.Ty, split.Quals, OS, policy, PlaceHolder); + const PrintingPolicy &policy, const Twine &PlaceHolder, + unsigned Indentation = 0) { + return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); } static void print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, - const Twine &PlaceHolder); + const Twine &PlaceHolder, + unsigned Indentation = 0); void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const { @@ -936,21 +962,24 @@ class QualType { const QualType &T; const PrintingPolicy &Policy; const Twine &PlaceHolder; + unsigned Indentation; public: StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, - const Twine &PlaceHolder) - : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { } + const Twine &PlaceHolder, unsigned Indentation) + : T(T), Policy(Policy), PlaceHolder(PlaceHolder), + Indentation(Indentation) { } friend raw_ostream &operator<<(raw_ostream &OS, const StreamedQualTypeHelper &SQT) { - SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder); + SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation); return OS; } }; StreamedQualTypeHelper stream(const PrintingPolicy &Policy, - const Twine &PlaceHolder = Twine()) const { - return StreamedQualTypeHelper(*this, Policy, PlaceHolder); + const Twine &PlaceHolder = Twine(), + unsigned Indentation = 0) const { + return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); } void dump(const char *s) const; @@ -1061,11 +1090,14 @@ class QualType { /// Strip Objective-C "__kindof" types from the given type. QualType stripObjCKindOfType(const ASTContext &ctx) const; + /// Remove all qualifiers including _Atomic. + QualType getAtomicUnqualifiedType() const; + private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the // caller. - static bool isConstant(QualType T, ASTContext& Ctx); + static bool isConstant(QualType T, const ASTContext& Ctx); static QualType getDesugaredType(QualType T, const ASTContext &Context); static SplitQualType getSplitDesugaredType(QualType T); static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); @@ -1353,7 +1385,7 @@ class Type : public ExtQualsTypeCommonBase { /// /// C++ 8.3.5p4: The return type, the parameter type list and the /// cv-qualifier-seq, [...], are part of the function type. - unsigned TypeQuals : 3; + unsigned TypeQuals : 4; /// \brief The ref-qualifier associated with a \c FunctionProtoType. /// @@ -1600,7 +1632,7 @@ class Type : public ExtQualsTypeCommonBase { bool isChar16Type() const; bool isChar32Type() const; bool isAnyCharacterType() const; - bool isIntegralType(ASTContext &Ctx) const; + bool isIntegralType(const ASTContext &Ctx) const; /// Determine whether this type is an integral or enumeration type. bool isIntegralOrEnumerationType() const; @@ -1699,18 +1731,9 @@ class Type : public ExtQualsTypeCommonBase { bool isNullPtrType() const; // C++0x nullptr_t bool isAtomicType() const; // C11 _Atomic() - bool isImage1dT() const; // OpenCL image1d_t - bool isImage1dArrayT() const; // OpenCL image1d_array_t - bool isImage1dBufferT() const; // OpenCL image1d_buffer_t - bool isImage2dT() const; // OpenCL image2d_t - bool isImage2dArrayT() const; // OpenCL image2d_array_t - bool isImage2dDepthT() const; // OpenCL image_2d_depth_t - bool isImage2dArrayDepthT() const; // OpenCL image_2d_array_depth_t - bool isImage2dMSAAT() const; // OpenCL image_2d_msaa_t - bool isImage2dArrayMSAAT() const; // OpenCL image_2d_array_msaa_t - bool isImage2dMSAATDepth() const; // OpenCL image_2d_msaa_depth_t - bool isImage2dArrayMSAATDepth() const; // OpenCL image_2d_array_msaa_depth_t - bool isImage3dT() const; // OpenCL image3d_t +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + bool is##Id##Type() const; +#include "clang/Basic/OpenCLImageTypes.def" bool isImageType() const; // Any OpenCL image type @@ -1875,6 +1898,11 @@ class Type : public ExtQualsTypeCommonBase { /// This should never be used when type qualifiers are meaningful. const Type *getArrayElementTypeNoTypeQual() const; + /// If this is a pointer type, return the pointee type. + /// If this is an array type, return the array element type. + /// This should never be used when type qualifiers are meaningful. + const Type *getPointeeOrArrayElementType() const; + /// If this is a pointer, ObjC object pointer, or block /// pointer, this returns the respective pointee. QualType getPointeeType() const; @@ -2011,6 +2039,10 @@ template <> inline const Class##Type *Type::castAs() const { \ class BuiltinType : public Type { public: enum Kind { +// OpenCL image types +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, +#include "clang/Basic/OpenCLImageTypes.def" +// All other builtin types #define BUILTIN_TYPE(Id, SingletonId) Id, #define LAST_BUILTIN_TYPE(Id) LastKind = Id #include "clang/AST/BuiltinTypes.def" @@ -2050,7 +2082,7 @@ class BuiltinType : public Type { } bool isFloatingPoint() const { - return getKind() >= Half && getKind() <= LongDouble; + return getKind() >= Half && getKind() <= Float128; } /// Determines whether the given kind corresponds to a placeholder type. @@ -2499,13 +2531,13 @@ class ConstantArrayType : public ArrayType { /// \brief Determine the number of bits required to address a member of // an array with the given element type and number of elements. - static unsigned getNumAddressingBits(ASTContext &Context, + static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements); /// \brief Determine the maximum number of active bits that an array's size /// can require, which limits the maximum size of the array. - static unsigned getMaxSizeBits(ASTContext &Context); + static unsigned getMaxSizeBits(const ASTContext &Context); void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getSize(), @@ -2990,7 +3022,7 @@ class FunctionType : public Type { /// \brief Determine the type of an expression that calls a function of /// this type. - QualType getCallResultType(ASTContext &Context) const { + QualType getCallResultType(const ASTContext &Context) const { return getReturnType().getNonLValueExprType(Context); } @@ -3040,6 +3072,74 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { /// type. class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { public: + /// Interesting information about a specific parameter that can't simply + /// be reflected in parameter's type. + /// + /// It makes sense to model language features this way when there's some + /// sort of parameter-specific override (such as an attribute) that + /// affects how the function is called. For example, the ARC ns_consumed + /// attribute changes whether a parameter is passed at +0 (the default) + /// or +1 (ns_consumed). This must be reflected in the function type, + /// but isn't really a change to the parameter type. + /// + /// One serious disadvantage of modelling language features this way is + /// that they generally do not work with language features that attempt + /// to destructure types. For example, template argument deduction will + /// not be able to match a parameter declared as + /// T (*)(U) + /// against an argument of type + /// void (*)(__attribute__((ns_consumed)) id) + /// because the substitution of T=void, U=id into the former will + /// not produce the latter. + class ExtParameterInfo { + enum { + ABIMask = 0x0F, + IsConsumed = 0x10 + }; + unsigned char Data; + public: + ExtParameterInfo() : Data(0) {} + + /// Return the ABI treatment of this parameter. + ParameterABI getABI() const { + return ParameterABI(Data & ABIMask); + } + ExtParameterInfo withABI(ParameterABI kind) const { + ExtParameterInfo copy = *this; + copy.Data = (copy.Data & ~ABIMask) | unsigned(kind); + return copy; + } + + /// Is this parameter considered "consumed" by Objective-C ARC? + /// Consumed parameters must have retainable object type. + bool isConsumed() const { + return (Data & IsConsumed); + } + ExtParameterInfo withIsConsumed(bool consumed) const { + ExtParameterInfo copy = *this; + if (consumed) { + copy.Data |= IsConsumed; + } else { + copy.Data &= ~IsConsumed; + } + return copy; + } + + unsigned char getOpaqueValue() const { return Data; } + static ExtParameterInfo getFromOpaqueValue(unsigned char data) { + ExtParameterInfo result; + result.Data = data; + return result; + } + + friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) { + return lhs.Data == rhs.Data; + } + friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) { + return lhs.Data != rhs.Data; + } + }; + struct ExceptionSpecInfo { ExceptionSpecInfo() : Type(EST_None), NoexceptExpr(nullptr), @@ -3067,11 +3167,11 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { struct ExtProtoInfo { ExtProtoInfo() : Variadic(false), HasTrailingReturn(false), TypeQuals(0), - RefQualifier(RQ_None), ConsumedParameters(nullptr) {} + RefQualifier(RQ_None), ExtParameterInfos(nullptr) {} ExtProtoInfo(CallingConv CC) : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), - RefQualifier(RQ_None), ConsumedParameters(nullptr) {} + RefQualifier(RQ_None), ExtParameterInfos(nullptr) {} ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) { ExtProtoInfo Result(*this); @@ -3085,7 +3185,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { unsigned char TypeQuals; RefQualifierKind RefQualifier; ExceptionSpecInfo ExceptionSpec; - const bool *ConsumedParameters; + const ExtParameterInfo *ExtParameterInfos; }; private: @@ -3112,8 +3212,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { /// The type of exception specification this function has. unsigned ExceptionSpecType : 4; - /// Whether this function has any consumed parameters. - unsigned HasAnyConsumedParams : 1; + /// Whether this function has extended parameter information. + unsigned HasExtParameterInfos : 1; /// Whether the function is variadic. unsigned Variadic : 1; @@ -3135,25 +3235,36 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { // instantiate this function type's exception specification, and the function // from which it should be instantiated. - // ConsumedParameters - A variable size array, following Exceptions - // and of length NumParams, holding flags indicating which parameters - // are consumed. This only appears if HasAnyConsumedParams is true. + // ExtParameterInfos - A variable size array, following the exception + // specification and of length NumParams, holding an ExtParameterInfo + // for each of the parameters. This only appears if HasExtParameterInfos + // is true. friend class ASTContext; // ASTContext creates these. - const bool *getConsumedParamsBuffer() const { - assert(hasAnyConsumedParams()); + const ExtParameterInfo *getExtParameterInfosBuffer() const { + assert(hasExtParameterInfos()); - // Find the end of the exceptions. - Expr *const *eh_end = reinterpret_cast(exception_end()); - if (getExceptionSpecType() == EST_ComputedNoexcept) - eh_end += 1; // NoexceptExpr - // The memory layout of these types isn't handled here, so - // hopefully this is never called for them? - assert(getExceptionSpecType() != EST_Uninstantiated && - getExceptionSpecType() != EST_Unevaluated); + // Find the end of the exception specification. + const char *ptr = reinterpret_cast(exception_begin()); + ptr += getExceptionSpecSize(); - return reinterpret_cast(eh_end); + return reinterpret_cast(ptr); + } + + size_t getExceptionSpecSize() const { + switch (getExceptionSpecType()) { + case EST_None: return 0; + case EST_DynamicNone: return 0; + case EST_MSAny: return 0; + case EST_BasicNoexcept: return 0; + case EST_Unparsed: return 0; + case EST_Dynamic: return getNumExceptions() * sizeof(QualType); + case EST_ComputedNoexcept: return sizeof(Expr*); + case EST_Uninstantiated: return 2 * sizeof(FunctionDecl*); + case EST_Unevaluated: return sizeof(FunctionDecl*); + } + llvm_unreachable("bad exception specification kind"); } public: @@ -3184,8 +3295,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) { EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl(); } - if (hasAnyConsumedParams()) - EPI.ConsumedParameters = getConsumedParamsBuffer(); + if (hasExtParameterInfos()) + EPI.ExtParameterInfos = getExtParameterInfosBuffer(); return EPI; } @@ -3300,11 +3411,41 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { return exception_begin() + NumExceptions; } - bool hasAnyConsumedParams() const { return HasAnyConsumedParams; } + /// Is there any interesting extra information for any of the parameters + /// of this function type? + bool hasExtParameterInfos() const { return HasExtParameterInfos; } + ArrayRef getExtParameterInfos() const { + assert(hasExtParameterInfos()); + return ArrayRef(getExtParameterInfosBuffer(), + getNumParams()); + } + /// Return a pointer to the beginning of the array of extra parameter + /// information, if present, or else null if none of the parameters + /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. + const ExtParameterInfo *getExtParameterInfosOrNull() const { + if (!hasExtParameterInfos()) + return nullptr; + return getExtParameterInfosBuffer(); + } + + ExtParameterInfo getExtParameterInfo(unsigned I) const { + assert(I < getNumParams() && "parameter index out of range"); + if (hasExtParameterInfos()) + return getExtParameterInfosBuffer()[I]; + return ExtParameterInfo(); + } + + ParameterABI getParameterABI(unsigned I) const { + assert(I < getNumParams() && "parameter index out of range"); + if (hasExtParameterInfos()) + return getExtParameterInfosBuffer()[I].getABI(); + return ParameterABI::Ordinary; + } + bool isParamConsumed(unsigned I) const { assert(I < getNumParams() && "parameter index out of range"); - if (hasAnyConsumedParams()) - return getConsumedParamsBuffer()[I]; + if (hasExtParameterInfos()) + return getExtParameterInfosBuffer()[I].isConsumed(); return false; } @@ -3518,6 +3659,28 @@ class UnaryTransformType : public Type { } }; +/// \brief Internal representation of canonical, dependent +/// __underlying_type(type) types. +/// +/// This class is used internally by the ASTContext to manage +/// canonical, dependent types, only. Clients will only see instances +/// of this class via UnaryTransformType nodes. +class DependentUnaryTransformType : public UnaryTransformType, + public llvm::FoldingSetNode { +public: + DependentUnaryTransformType(const ASTContext &C, QualType BaseType, + UTTKind UKind); + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getBaseType(), getUTTKind()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, + UTTKind UKind) { + ID.AddPointer(BaseType.getAsOpaquePtr()); + ID.AddInteger((unsigned)UKind); + } +}; + class TagType : public Type { /// Stores the TagDecl associated with this type. The decl may point to any /// TagDecl that declares the entity. @@ -3626,10 +3789,13 @@ class AttributedType : public Type, public llvm::FoldingSetNode { attr_stdcall, attr_thiscall, attr_pascal, + attr_swiftcall, attr_vectorcall, attr_inteloclbicc, attr_ms_abi, attr_sysv_abi, + attr_preserve_most, + attr_preserve_all, attr_ptr32, attr_ptr64, attr_sptr, @@ -4002,19 +4168,18 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType unsigned NumArgs : 31; /// Whether this template specialization type is a substituted type alias. - bool TypeAlias : 1; + unsigned TypeAlias : 1; TemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, QualType Canon, + ArrayRef Args, + QualType Canon, QualType Aliased); friend class ASTContext; // ASTContext creates these public: /// Determine whether any of the given template arguments are dependent. - static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, - unsigned NumArgs, + static bool anyDependentTemplateArguments(ArrayRef Args, bool &InstantiationDependent); static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, @@ -4023,14 +4188,12 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. static void PrintTemplateArgumentList(raw_ostream &OS, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, const PrintingPolicy &Policy, bool SkipBrackets = false); static void PrintTemplateArgumentList(raw_ostream &OS, - const TemplateArgumentLoc *Args, - unsigned NumArgs, + ArrayRef Args, const PrintingPolicy &Policy); static void PrintTemplateArgumentList(raw_ostream &OS, @@ -4087,20 +4250,23 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType /// \pre \c isArgType(Arg) const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h + ArrayRef template_arguments() const { + return {getArgs(), NumArgs}; + } + bool isSugared() const { return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); } QualType desugar() const { return getCanonicalTypeInternal(); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { - Profile(ID, Template, getArgs(), NumArgs, Ctx); + Profile(ID, Template, template_arguments(), Ctx); if (isTypeAlias()) getAliasedType().Profile(ID); } static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef Args, const ASTContext &Context); static bool classof(const Type *T) { @@ -4143,6 +4309,8 @@ class InjectedClassNameType : public Type { friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not // currently suitable for AST reading, too much // interdependencies. + friend class ASTNodeImporter; + InjectedClassNameType(CXXRecordDecl *D, QualType TST) : Type(InjectedClassName, QualType(), /*Dependent=*/true, /*InstantiationDependent=*/true, @@ -4402,8 +4570,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args, + ArrayRef Args, QualType Canon); friend class ASTContext; // ASTContext creates these @@ -4422,6 +4589,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h + ArrayRef template_arguments() const { + return {getArgs(), NumArgs}; + } + typedef const TemplateArgument * iterator; iterator begin() const { return getArgs(); } iterator end() const; // inline in TemplateBase.h @@ -4430,7 +4601,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { - Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs()); + Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs}); } static void Profile(llvm::FoldingSetNodeID &ID, @@ -4438,8 +4609,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType ElaboratedTypeKeyword Keyword, NestedNameSpecifier *Qualifier, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args); + ArrayRef Args); static bool classof(const Type *T) { return T->getTypeClass() == DependentTemplateSpecialization; @@ -5194,7 +5364,8 @@ inline void QualType::removeLocalVolatile() { inline void QualType::removeLocalCVRQualifiers(unsigned Mask) { assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits"); - assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask); + static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask, + "Fast bits differ from CVR bits!"); // Fast path: we don't need to touch the slow qualifiers. removeLocalFastQualifiers(Mask); @@ -5230,9 +5401,9 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { /// "int". However, it is not more qualified than "const volatile /// int". inline bool QualType::isMoreQualifiedThan(QualType other) const { - Qualifiers myQuals = getQualifiers(); - Qualifiers otherQuals = other.getQualifiers(); - return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals)); + Qualifiers MyQuals = getQualifiers(); + Qualifiers OtherQuals = other.getQualifiers(); + return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals)); } /// Determine whether this type is at last @@ -5240,7 +5411,13 @@ inline bool QualType::isMoreQualifiedThan(QualType other) const { /// int" is at least as qualified as "const int", "volatile int", /// "int", and "const volatile int". inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { - return getQualifiers().compatiblyIncludes(other.getQualifiers()); + Qualifiers OtherQuals = other.getQualifiers(); + + // Ignore __unaligned qualifier if this type is a void. + if (getUnqualifiedType()->isVoidType()) + OtherQuals.removeUnaligned(); + + return getQualifiers().compatiblyIncludes(OtherQuals); } /// If Type is a reference type (e.g., const @@ -5417,53 +5594,11 @@ inline bool Type::isObjCBuiltinType() const { return isObjCIdType() || isObjCClassType() || isObjCSelType(); } -inline bool Type::isImage1dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1d); -} - -inline bool Type::isImage1dArrayT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1dArray); -} - -inline bool Type::isImage1dBufferT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer); -} - -inline bool Type::isImage2dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2d); -} - -inline bool Type::isImage2dArrayT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArray); -} - -inline bool Type::isImage2dDepthT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dDepth); -} - -inline bool Type::isImage2dArrayDepthT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayDepth); -} - -inline bool Type::isImage2dMSAAT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAA); -} - -inline bool Type::isImage2dArrayMSAAT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAA); -} - -inline bool Type::isImage2dMSAATDepth() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAADepth); -} - -inline bool Type::isImage2dArrayMSAATDepth() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAADepth); -} - -inline bool Type::isImage3dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage3d); -} +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + inline bool Type::is##Id##Type() const { \ + return isSpecificBuiltinType(BuiltinType::Id); \ + } +#include "clang/Basic/OpenCLImageTypes.def" inline bool Type::isSamplerT() const { return isSpecificBuiltinType(BuiltinType::OCLSampler); @@ -5490,11 +5625,10 @@ inline bool Type::isReserveIDT() const { } inline bool Type::isImageType() const { - return isImage3dT() || isImage2dT() || isImage2dArrayT() || - isImage2dDepthT() || isImage2dArrayDepthT() || isImage2dMSAAT() || - isImage2dArrayMSAAT() || isImage2dMSAATDepth() || - isImage2dArrayMSAATDepth() || isImage1dT() || isImage1dArrayT() || - isImage1dBufferT(); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() || + return +#include "clang/Basic/OpenCLImageTypes.def" + 0; // end boolean or operation } inline bool Type::isPipeType() const { @@ -5644,6 +5778,15 @@ inline const Type *Type::getBaseElementTypeUnsafe() const { return type; } +inline const Type *Type::getPointeeOrArrayElementType() const { + const Type *type = this; + if (type->isAnyPointerType()) + return type->getPointeeType().getTypePtr(); + else if (type->isArrayType()) + return type->getBaseElementTypeUnsafe(); + return type; +} + /// Insertion operator for diagnostics. This allows sending QualType's into a /// diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 29035a41776..67adf4a638b 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -254,7 +254,7 @@ class QualifiedTypeLoc : public TypeLoc { unsigned align = TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); uintptr_t dataInt = reinterpret_cast(Data); - dataInt = llvm::RoundUpToAlignment(dataInt, align); + dataInt = llvm::alignTo(dataInt, align); return UnqualTypeLoc(getTypePtr(), reinterpret_cast(dataInt)); } @@ -353,7 +353,7 @@ class ConcreteTypeLoc : public Base { unsigned getLocalDataSize() const { unsigned size = sizeof(LocalData); unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); - size = llvm::RoundUpToAlignment(size, extraAlign); + size = llvm::alignTo(size, extraAlign); size += asDerived()->getExtraLocalDataSize(); return size; } @@ -399,14 +399,14 @@ class ConcreteTypeLoc : public Base { void *getExtraLocalData() const { unsigned size = sizeof(LocalData); unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); - size = llvm::RoundUpToAlignment(size, extraAlign); + size = llvm::alignTo(size, extraAlign); return reinterpret_cast(Base::Data) + size; } void *getNonLocalData() const { uintptr_t data = reinterpret_cast(Base::Data); data += asDerived()->getLocalDataSize(); - data = llvm::RoundUpToAlignment(data, getNextTypeAlign()); + data = llvm::alignTo(data, getNextTypeAlign()); return reinterpret_cast(data); } @@ -538,7 +538,7 @@ class BuiltinTypeLoc : public ConcreteTypeLocgetKind(); return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) - || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) + || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128) || bk == BuiltinType::UChar || bk == BuiltinType::SChar; } diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index 26ee1cf71c8..c1be2aa0f20 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -59,8 +59,13 @@ class UnresolvedSetImpl { // UnresolvedSet. private: template friend class UnresolvedSet; - UnresolvedSetImpl() {} - UnresolvedSetImpl(const UnresolvedSetImpl &) {} + UnresolvedSetImpl() = default; + UnresolvedSetImpl(const UnresolvedSetImpl &) = default; + UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default; + + // FIXME: Switch these to "= default" once MSVC supports generating move ops + UnresolvedSetImpl(UnresolvedSetImpl &&) {} + UnresolvedSetImpl &operator=(UnresolvedSetImpl &&) { return *this; } public: // We don't currently support assignment through this iterator, so we might diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h index 92ec92c299c..042408859c9 100644 --- a/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/include/clang/ASTMatchers/ASTMatchFinder.h @@ -241,6 +241,11 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, ASTContext &Context); /// @} +/// \brief Returns the results of matching \p Matcher on the translation unit of +/// \p Context and collects the \c BoundNodes of all callback invocations. +template +SmallVector match(MatcherT Matcher, ASTContext &Context); + /// \brief Returns the first result of type \c NodeT bound to \p BoundTo. /// /// Returns \c NULL if there is no match, or if the matching node cannot be @@ -288,6 +293,16 @@ match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) { return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context); } +template +SmallVector +match(MatcherT Matcher, ASTContext &Context) { + internal::CollectMatchesCallback Callback; + MatchFinder Finder; + Finder.addMatcher(Matcher, &Callback); + Finder.matchAST(Context); + return std::move(Callback.Nodes); +} + } // end namespace ast_matchers } // end namespace clang diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index e6ba8778f24..aef4b4eafd9 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -163,11 +163,35 @@ const internal::VariadicDynCastAllOfMatcher /// Given /// \code /// typedef int X; +/// using Y = int; /// \endcode /// typedefDecl() -/// matches "typedef int X" +/// matches "typedef int X", but not "using Y = int" const internal::VariadicDynCastAllOfMatcher typedefDecl; +/// \brief Matches typedef name declarations. +/// +/// Given +/// \code +/// typedef int X; +/// using Y = int; +/// \endcode +/// typedefNameDecl() +/// matches "typedef int X" and "using Y = int" +const internal::VariadicDynCastAllOfMatcher + typedefNameDecl; + +/// \brief Matches type alias declarations. +/// +/// Given +/// \code +/// typedef int X; +/// using Y = int; +/// \endcode +/// typeAliasDecl() +/// matches "using Y = int", but not "typedef int X" +const internal::VariadicDynCastAllOfMatcher typeAliasDecl; + /// \brief Matches AST nodes that were expanded within the main-file. /// /// Example matches X but not Y @@ -282,6 +306,17 @@ const internal::VariadicDynCastAllOfMatcher /// \endcode const internal::VariadicDynCastAllOfMatcher namedDecl; +/// \brief Matches a declaration of label. +/// +/// Given +/// \code +/// goto FOO; +/// FOO: bar(); +/// \endcode +/// labelDecl() +/// matches 'FOO:' +const internal::VariadicDynCastAllOfMatcher labelDecl; + /// \brief Matches a declaration of a namespace. /// /// Given @@ -447,7 +482,7 @@ const internal::VariadicDynCastAllOfMatcher< /// }; /// \endcode /// fieldDecl(isPublic()) -/// matches 'int a;' +/// matches 'int a;' AST_MATCHER(Decl, isPublic) { return Node.getAccess() == AS_public; } @@ -463,7 +498,7 @@ AST_MATCHER(Decl, isPublic) { /// }; /// \endcode /// fieldDecl(isProtected()) -/// matches 'int b;' +/// matches 'int b;' AST_MATCHER(Decl, isProtected) { return Node.getAccess() == AS_protected; } @@ -479,11 +514,43 @@ AST_MATCHER(Decl, isProtected) { /// }; /// \endcode /// fieldDecl(isPrivate()) -/// matches 'int c;' +/// matches 'int c;' AST_MATCHER(Decl, isPrivate) { return Node.getAccess() == AS_private; } +/// \brief Matches non-static data members that are bit-fields. +/// +/// Given +/// \code +/// class C { +/// int a : 2; +/// int b; +/// }; +/// \endcode +/// fieldDecl(isBitField()) +/// matches 'int a;' but not 'int b;'. +AST_MATCHER(FieldDecl, isBitField) { + return Node.isBitField(); +} + +/// \brief Matches non-static data members that are bit-fields. +/// +/// Given +/// \code +/// class C { +/// int a : 2; +/// int b : 4; +/// int c : 2; +/// }; +/// \endcode +/// fieldDecl(isBitField()) +/// matches 'int a;' and 'int c;' but not 'int b;'. +AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) { + return Node.isBitField() && + Node.getBitWidthValue(Finder->getASTContext()) == Width; +} + /// \brief Matches a declaration that has been implicitly added /// by the compiler (eg. implicit default/copy constructors). AST_MATCHER(Decl, isImplicit) { @@ -513,6 +580,32 @@ AST_POLYMORPHIC_MATCHER_P( Builder); } +/// \brief Matches expressions that match InnerMatcher after any implicit AST +/// nodes are stripped off. +/// +/// Parentheses and explicit casts are not discarded. +/// Given +/// \code +/// class C {}; +/// C a = C(); +/// C b; +/// C c = b; +/// \endcode +/// The matchers +/// \code +/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr()))) +/// \endcode +/// would match the declarations for a, b, and c. +/// While +/// \code +/// varDecl(hasInitializer(cxxConstructExpr())) +/// \endcode +/// only match the declarations for b and c. +AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher, + InnerMatcher) { + return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder); +} + /// \brief Matches expressions that match InnerMatcher after any implicit casts /// are stripped off. /// @@ -590,6 +683,22 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder); } +/// \brief Matches types that match InnerMatcher after any parens are stripped. +/// +/// Given +/// \code +/// void (*fp)(void); +/// \endcode +/// The matcher +/// \code +/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) +/// \endcode +/// would match the declaration for fp. +AST_MATCHER_P(QualType, ignoringParens, + internal::Matcher, InnerMatcher) { + return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder); +} + /// \brief Matches classTemplateSpecializations where the n'th TemplateArgument /// matches the given InnerMatcher. /// @@ -976,6 +1085,43 @@ const internal::VariadicDynCastAllOfMatcher< /// matches "{ 1, 2 }" and "{ 5, 6 }" const internal::VariadicDynCastAllOfMatcher initListExpr; +/// \brief Matches the syntactic form of init list expressions +/// (if expression have it). +AST_MATCHER_P(InitListExpr, hasSyntacticForm, + internal::Matcher, InnerMatcher) { + const Expr *SyntForm = Node.getSyntacticForm(); + return (SyntForm != nullptr && + InnerMatcher.matches(*SyntForm, Finder, Builder)); +} + +/// \brief Matches implicit initializers of init list expressions. +/// +/// Given +/// \code +/// point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; +/// \endcode +/// implicitValueInitExpr() +/// matches "[0].y" (implicitly) +const internal::VariadicDynCastAllOfMatcher +implicitValueInitExpr; + +/// \brief Matches paren list expressions. +/// ParenListExprs don't have a predefined type and are used for late parsing. +/// In the final AST, they can be met in template declarations. +/// +/// Given +/// \code +/// template class X { +/// void f() { +/// X x(*this); +/// int a = 0, b = 1; int i = (a, b); +/// } +/// }; +/// \endcode +/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b) +/// has a predefined type and is a ParenExpr, not a ParenListExpr. +const internal::VariadicDynCastAllOfMatcher parenListExpr; + /// \brief Matches substitutions of non-type template parameters. /// /// Given @@ -1014,6 +1160,24 @@ const internal::VariadicDynCastAllOfMatcher< Decl, UsingDirectiveDecl> usingDirectiveDecl; +/// \brief Matches reference to a name that can be looked up during parsing +/// but could not be resolved to a specific declaration. +/// +/// Given +/// \code +/// template +/// T foo() { T a; return a; } +/// template +/// void bar() { +/// foo(); +/// } +/// \endcode +/// unresolvedLookupExpr() +/// matches \code foo() \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + UnresolvedLookupExpr> unresolvedLookupExpr; + /// \brief Matches unresolved using value declarations. /// /// Given @@ -1048,6 +1212,17 @@ const internal::VariadicDynCastAllOfMatcher< Decl, UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; +/// \brief Matches parentheses used in expressions. +/// +/// Example matches (foo() + 1) +/// \code +/// int foo() { return 1; } +/// int a = (foo() + 1); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + ParenExpr> parenExpr; + /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f @@ -1357,6 +1532,18 @@ const internal::VariadicDynCastAllOfMatcher gotoStmt; /// matches 'FOO:' const internal::VariadicDynCastAllOfMatcher labelStmt; +/// \brief Matches address of label statements (GNU extension). +/// +/// Given +/// \code +/// FOO: bar(); +/// void *ptr = &&FOO; +/// goto *bar; +/// \endcode +/// addrLabelExpr() +/// matches '&&FOO' +const internal::VariadicDynCastAllOfMatcher addrLabelExpr; + /// \brief Matches switch statements. /// /// Given @@ -1465,7 +1652,8 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches "abcd", L"abcd" /// \code -/// char *s = "abcd"; wchar_t *ws = L"abcd" +/// char *s = "abcd"; +/// wchar_t *ws = L"abcd"; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, @@ -1478,7 +1666,8 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches 'a', L'a' /// \code -/// char ch = 'a'; wchar_t chw = L'a'; +/// char ch = 'a'; +/// wchar_t chw = L'a'; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, @@ -1514,7 +1703,8 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example match: {1}, (1, 2) /// \code -/// int array[4] = {1}; vector int myvec = (vector int)(1, 2); +/// int array[4] = {1}; +/// vector int myvec = (vector int)(1, 2); /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, @@ -1526,9 +1716,22 @@ const internal::VariadicDynCastAllOfMatcher< CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; /// \brief Matches GNU __null expression. -const internal::VariadicDynCastAllOfMatcher< - Stmt, - GNUNullExpr> gnuNullExpr; +const internal::VariadicDynCastAllOfMatcher gnuNullExpr; + +/// \brief Matches atomic builtins. +/// Example matches __atomic_load_n(ptr, 1) +/// \code +/// void foo() { int *ptr; __atomic_load_n(ptr, 1); } +/// \endcode +const internal::VariadicDynCastAllOfMatcher atomicExpr; + +/// \brief Matches statement expression (GNU extension). +/// +/// Example match: ({ int X = 4; X; }) +/// \code +/// int C = ({ int X = 4; X; }); +/// \endcode +const internal::VariadicDynCastAllOfMatcher stmtExpr; /// \brief Matches binary operator expressions. /// @@ -1560,6 +1763,28 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, ConditionalOperator> conditionalOperator; +/// \brief Matches binary conditional operator expressions (GNU extension). +/// +/// Example matches a ?: b +/// \code +/// (a ?: b) + 42; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + BinaryConditionalOperator> binaryConditionalOperator; + +/// \brief Matches opaque value expressions. They are used as helpers +/// to reference another expressions and can be met +/// in BinaryConditionalOperators, for example. +/// +/// Example matches 'a' +/// \code +/// (a ?: c) + 42; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + OpaqueValueExpr> opaqueValueExpr; + /// \brief Matches a C++ static_assert declaration. /// /// Example: @@ -1716,6 +1941,41 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXTemporaryObjectExpr> cxxTemporaryObjectExpr; +/// \brief Matches predefined identifier expressions [C99 6.4.2.2]. +/// +/// Example: Matches __func__ +/// \code +/// printf("%s", __func__); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + PredefinedExpr> predefinedExpr; + +/// \brief Matches C99 designated initializer expressions [C99 6.7.8]. +/// +/// Example: Matches { [2].y = 1.0, [0].x = 1.0 } +/// \code +/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 }; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + DesignatedInitExpr> designatedInitExpr; + +/// \brief Matches designated initializer expressions that contain +/// a specific number of designators. +/// +/// Example: Given +/// \code +/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 }; +/// point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }; +/// \endcode +/// designatorCountIs(2) +/// matches '{ [2].y = 1.0, [0].x = 1.0 }', +/// but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'. +AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) { + return Node.size() == N; +} + /// \brief Matches \c QualTypes in the clang AST. const internal::VariadicAllOfMatcher qualType; @@ -1834,9 +2094,25 @@ inline internal::Matcher sizeOfExpr( /// namespace a { namespace b { class X; } } /// \endcode inline internal::Matcher hasName(const std::string &Name) { - return internal::Matcher(new internal::HasNameMatcher(Name)); + std::vector Names; + Names.push_back(Name); + return internal::Matcher(new internal::HasNameMatcher(Names)); } +/// \brief Matches NamedDecl nodes that have any of the specified names. +/// +/// This matcher is only provided as a performance optimization of hasName. +/// \code +/// hasAnyName(a, b, c) +/// \endcode +/// is equivalent to, but faster than +/// \code +/// anyOf(hasName(a), hasName(b), hasName(c)) +/// \endcode +const internal::VariadicFunction, StringRef, + internal::hasAnyNameFunc> + hasAnyName = {}; + /// \brief Matches NamedDecl nodes whose fully qualified names contain /// a substring matched by the given RegExp. /// @@ -1953,6 +2229,19 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher, Node.method_end(), Finder, Builder); } +/// \brief Matches the generated class of lambda expressions. +/// +/// Given: +/// \code +/// auto x = []{}; +/// \endcode +/// +/// \c cxxRecordDecl(isLambda()) matches the implicit class declaration of +/// \c decltype(x) +AST_MATCHER(CXXRecordDecl, isLambda) { + return Node.isLambda(); +} + /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. /// @@ -1967,6 +2256,10 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher, /// ChildT must be an AST base type. /// /// Usable as: Any Matcher +/// Note that has is direct matcher, so it also matches things like implicit +/// casts and paren casts. If you are matching with expr then you should +/// probably consider using ignoringParenImpCasts like: +/// has(ignoringParenImpCasts(expr())). const internal::ArgumentAdaptingMatcherFunc LLVM_ATTRIBUTE_UNUSED has = {}; @@ -2117,8 +2410,8 @@ const internal::VariadicOperatorMatcherFunc<1, 1> unless = { /// /// Usable as: Matcher, Matcher, /// Matcher, Matcher, Matcher, -/// Matcher, Matcher, Matcher, -/// Matcher, Matcher, +/// Matcher, Matcher, Matcher, +/// Matcher, Matcher, Matcher, /// Matcher, Matcher, /// Matcher, Matcher inline internal::PolymorphicMatcherWithParam1< @@ -2287,14 +2580,17 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher, InnerMatcher, /// /// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) /// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) +/// and U (matcher = typedefDecl(hasType(asString("int"))) /// \code /// class X {}; /// void y(X &x) { x; X z; } +/// typedef int U; /// \endcode AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, ValueDecl), + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl), internal::Matcher, InnerMatcher, 0) { - return InnerMatcher.matches(Node.getType(), Finder, Builder); + return InnerMatcher.matches(internal::getUnderlyingType(Node), + Finder, Builder); } /// \brief Overloaded to match the declaration of the expression's or value @@ -2829,18 +3125,13 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) { /// matches x(1, y, 42) /// with hasAnyArgument(...) /// matching y -/// -/// FIXME: Currently this will ignore parentheses and implicit casts on -/// the argument before applying the inner matcher. We'll want to remove -/// this to allow for greater control by the user once \c ignoreImplicit() -/// has been implemented. AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, CXXConstructExpr), internal::Matcher, InnerMatcher) { for (const Expr *Arg : Node.arguments()) { BoundNodesTreeBuilder Result(*Builder); - if (InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, &Result)) { + if (InnerMatcher.matches(*Arg, Finder, &Result)) { *Builder = std::move(Result); return true; } @@ -2853,6 +3144,22 @@ AST_MATCHER(CXXConstructExpr, isListInitialization) { return Node.isListInitialization(); } +/// \brief Matches a constructor call expression which requires +/// zero initialization. +/// +/// Given +/// \code +/// void foo() { +/// struct point { double x; double y; }; +/// point pt[2] = { { 1.0, 2.0 } }; +/// } +/// \endcode +/// initListExpr(has(cxxConstructExpr(requiresZeroInitialization())) +/// will match the implicit array filler for pt[1]. +AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) { + return Node.requiresZeroInitialization(); +} + /// \brief Matches the n'th parameter of a function declaration. /// /// Given @@ -2871,6 +3178,60 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, *Node.getParamDecl(N), Finder, Builder)); } +/// \brief Matches all arguments and their respective ParmVarDecl. +/// +/// Given +/// \code +/// void f(int i); +/// int y; +/// f(y); +/// \endcode +/// callExpr( +/// forEachArgumentWithParam( +/// declRefExpr(to(varDecl(hasName("y")))), +/// parmVarDecl(hasType(isInteger())) +/// )) +/// matches f(y); +/// with declRefExpr(...) +/// matching int y +/// and parmVarDecl(...) +/// matching int i +AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, + AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, + CXXConstructExpr), + internal::Matcher, ArgMatcher, + internal::Matcher, ParamMatcher) { + BoundNodesTreeBuilder Result; + // The first argument of an overloaded member operator is the implicit object + // argument of the method which should not be matched against a parameter, so + // we skip over it here. + BoundNodesTreeBuilder Matches; + unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl())) + .matches(Node, Finder, &Matches) + ? 1 + : 0; + int ParamIndex = 0; + bool Matched = false; + for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) { + BoundNodesTreeBuilder ArgMatches(*Builder); + if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), + Finder, &ArgMatches)) { + BoundNodesTreeBuilder ParamMatches(ArgMatches); + if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl( + hasParameter(ParamIndex, ParamMatcher)))), + callExpr(callee(functionDecl( + hasParameter(ParamIndex, ParamMatcher)))))) + .matches(Node, Finder, &ParamMatches)) { + Result.addMatch(ParamMatches); + Matched = true; + } + } + ++ParamIndex; + } + *Builder = std::move(Result); + return Matched; +} + /// \brief Matches any parameter of a function declaration. /// /// Does not match the 'this' parameter of a method. @@ -2889,16 +3250,27 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter, Node.param_end(), Finder, Builder); } -/// \brief Matches \c FunctionDecls that have a specific parameter count. +/// \brief Matches \c FunctionDecls and \c FunctionProtoTypes that have a +/// specific parameter count. /// /// Given /// \code /// void f(int i) {} /// void g(int i, int j) {} +/// void h(int i, int j); +/// void j(int i); +/// void k(int x, int y, int z, ...); /// \endcode /// functionDecl(parameterCountIs(2)) -/// matches g(int i, int j) {} -AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) { +/// matches void g(int i, int j) {} +/// functionProtoType(parameterCountIs(2)) +/// matches void h(int i, int j) +/// functionProtoType(parameterCountIs(3)) +/// matches void k(int x, int y, int z, ...); +AST_POLYMORPHIC_MATCHER_P(parameterCountIs, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + FunctionProtoType), + unsigned, N) { return Node.getNumParams() == N; } @@ -2942,6 +3314,42 @@ AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } +/// \brief Matches defaulted function declarations. +/// +/// Given: +/// \code +/// class A { ~A(); }; +/// class B { ~B() = default; }; +/// \endcode +/// functionDecl(isDefaulted()) +/// matches the declaration of ~B, but not ~A. +AST_MATCHER(FunctionDecl, isDefaulted) { + return Node.isDefaulted(); +} + +/// \brief Matches functions that have a dynamic exception specification. +/// +/// Given: +/// \code +/// void f(); +/// void g() noexcept; +/// void h() noexcept(true); +/// void i() noexcept(false); +/// void j() throw(); +/// void k() throw(int); +/// void l() throw(...); +/// \endcode +/// functionDecl(hasDynamicExceptionSpec()) and +/// functionProtoType(hasDynamicExceptionSpec()) +/// match the declarations of j, k, and l, but not f, g, h, or i. +AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + FunctionProtoType)) { + if (const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node)) + return FnTy->hasDynamicExceptionSpec(); + return false; +} + /// \brief Matches functions that have a non-throwing exception specification. /// /// Given: @@ -2952,10 +3360,12 @@ AST_MATCHER(FunctionDecl, isDeleted) { /// void i() throw(int); /// void j() noexcept(false); /// \endcode -/// functionDecl(isNoThrow()) -/// matches the declarations of g, and h, but not f, i or j. -AST_MATCHER(FunctionDecl, isNoThrow) { - const auto *FnTy = Node.getType()->getAs(); +/// functionDecl(isNoThrow()) and functionProtoType(isNoThrow()) +/// match the declarations of g, and h, but not f, i or j. +AST_POLYMORPHIC_MATCHER(isNoThrow, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + FunctionProtoType)) { + const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node); // If the function does not have a prototype, then it is assumed to be a // throwing function (as it would if the function did not have any exception @@ -2967,7 +3377,7 @@ AST_MATCHER(FunctionDecl, isNoThrow) { if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType())) return true; - return FnTy->isNothrow(Node.getASTContext()); + return FnTy->isNothrow(Finder->getASTContext()); } /// \brief Matches constexpr variable and function declarations. @@ -2988,17 +3398,17 @@ AST_POLYMORPHIC_MATCHER(isConstexpr, } /// \brief Matches the condition expression of an if statement, for loop, -/// or conditional operator. +/// switch statement or conditional operator. /// /// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) /// \code /// if (true) {} /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasCondition, - AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, - WhileStmt, DoStmt, - ConditionalOperator), - internal::Matcher, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P( + hasCondition, + AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, WhileStmt, DoStmt, + SwitchStmt, AbstractConditionalOperator), + internal::Matcher, InnerMatcher) { const Expr *const Condition = Node.getCond(); return (Condition != nullptr && InnerMatcher.matches(*Condition, Finder, Builder)); @@ -3114,8 +3524,8 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, return false; } -/// \brief Matches a 'for', 'while', or 'do while' statement that has -/// a given body. +/// \brief Matches a 'for', 'while', 'do while' statement or a function +/// definition that has a given body. /// /// Given /// \code @@ -3128,15 +3538,16 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, AST_POLYMORPHIC_MATCHER_P(hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, WhileStmt, - CXXForRangeStmt), + CXXForRangeStmt, + FunctionDecl), internal::Matcher, InnerMatcher) { - const Stmt *const Statement = Node.getBody(); + const Stmt *const Statement = internal::GetBodyMatcher::get(Node); return (Statement != nullptr && InnerMatcher.matches(*Statement, Finder, Builder)); } /// \brief Matches compound statements where at least one substatement matches -/// a given matcher. +/// a given matcher. Also matches StmtExprs that have CompoundStmt as children. /// /// Given /// \code @@ -3146,10 +3557,13 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, /// matches '{ {}; 1+2; }' /// with compoundStmt() /// matching '{}' -AST_MATCHER_P(CompoundStmt, hasAnySubstatement, - internal::Matcher, InnerMatcher) { - return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(), - Node.body_end(), Finder, Builder); +AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement, + AST_POLYMORPHIC_SUPPORTED_TYPES(CompoundStmt, + StmtExpr), + internal::Matcher, InnerMatcher) { + const CompoundStmt *CS = CompoundStmtMatcher::get(Node); + return CS && matchesFirstInPointerRange(InnerMatcher, CS->body_begin(), + CS->body_end(), Finder, Builder); } /// \brief Checks that a compound statement contains a specific number of @@ -3248,21 +3662,43 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand, InnerMatcher.matches(*Operand, Finder, Builder)); } -/// \brief Matches if the cast's source expression matches the given matcher. +/// \brief Matches if the cast's source expression +/// or opaque value's source expression matches the given matcher. /// -/// Example: matches "a string" (matcher = -/// hasSourceExpression(cxxConstructExpr())) +/// Example 1: matches "a string" +/// (matcher = castExpr(hasSourceExpression(cxxConstructExpr()))) /// \code /// class URL { URL(string); }; /// URL url = "a string"; /// \endcode -AST_MATCHER_P(CastExpr, hasSourceExpression, - internal::Matcher, InnerMatcher) { - const Expr* const SubExpression = Node.getSubExpr(); +/// +/// Example 2: matches 'b' (matcher = +/// opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr()))) +/// \code +/// int a = b ?: 1; +/// \endcode + +AST_POLYMORPHIC_MATCHER_P(hasSourceExpression, + AST_POLYMORPHIC_SUPPORTED_TYPES(CastExpr, + OpaqueValueExpr), + internal::Matcher, InnerMatcher) { + const Expr *const SubExpression = + internal::GetSourceExpressionMatcher::get(Node); return (SubExpression != nullptr && InnerMatcher.matches(*SubExpression, Finder, Builder)); } +/// \brief Matches casts that has a given cast kind. +/// +/// Example: matches the implicit cast around \c 0 +/// (matcher = castExpr(hasCastKind(CK_NullToPointer))) +/// \code +/// int *p = 0; +/// \endcode +AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { + return Node.getCastKind() == Kind; +} + /// \brief Matches casts whose destination type matches a given matcher. /// /// (Note: Clang's AST refers to other conversions as "casts" too, and calls @@ -3320,24 +3756,31 @@ AST_MATCHER(RecordDecl, isClass) { /// \brief Matches the true branch expression of a conditional operator. /// -/// Example matches a +/// Example 1 (conditional ternary operator): matches a /// \code /// condition ? a : b /// \endcode -AST_MATCHER_P(ConditionalOperator, hasTrueExpression, +/// +/// Example 2 (conditional binary operator): matches opaqueValueExpr(condition) +/// \code +/// condition ?: b +/// \endcode +AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression, internal::Matcher, InnerMatcher) { const Expr *Expression = Node.getTrueExpr(); return (Expression != nullptr && InnerMatcher.matches(*Expression, Finder, Builder)); } -/// \brief Matches the false branch expression of a conditional operator. +/// \brief Matches the false branch expression of a conditional operator +/// (binary or ternary). /// /// Example matches b /// \code /// condition ? a : b +/// condition ?: b /// \endcode -AST_MATCHER_P(ConditionalOperator, hasFalseExpression, +AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression, internal::Matcher, InnerMatcher) { const Expr *Expression = Node.getFalseExpr(); return (Expression != nullptr && @@ -3401,6 +3844,47 @@ AST_MATCHER_P(CXXMethodDecl, ofClass, InnerMatcher.matches(*Parent, Finder, Builder)); } +/// \brief Matches each method overriden by the given method. This matcher may +/// produce multiple matches. +/// +/// Given +/// \code +/// class A { virtual void f(); }; +/// class B : public A { void f(); }; +/// class C : public B { void f(); }; +/// \endcode +/// cxxMethodDecl(ofClass(hasName("C")), +/// forEachOverridden(cxxMethodDecl().bind("b"))).bind("d") +/// matches once, with "b" binding "A::f" and "d" binding "C::f" (Note +/// that B::f is not overridden by C::f). +/// +/// The check can produce multiple matches in case of multiple inheritance, e.g. +/// \code +/// class A1 { virtual void f(); }; +/// class A2 { virtual void f(); }; +/// class C : public A1, public A2 { void f(); }; +/// \endcode +/// cxxMethodDecl(ofClass(hasName("C")), +/// forEachOverridden(cxxMethodDecl().bind("b"))).bind("d") +/// matches twice, once with "b" binding "A1::f" and "d" binding "C::f", and +/// once with "b" binding "A2::f" and "d" binding "C::f". +AST_MATCHER_P(CXXMethodDecl, forEachOverridden, + internal::Matcher, InnerMatcher) { + BoundNodesTreeBuilder Result; + bool Matched = false; + for (const auto *Overridden : Node.overridden_methods()) { + BoundNodesTreeBuilder OverriddenBuilder(*Builder); + const bool OverriddenMatched = + InnerMatcher.matches(*Overridden, Finder, &OverriddenBuilder); + if (OverriddenMatched) { + Matched = true; + Result.addMatch(OverriddenBuilder); + } + } + *Builder = std::move(Result); + return Matched; +} + /// \brief Matches if the given method declaration is virtual. /// /// Given @@ -3415,6 +3899,24 @@ AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); } +/// \brief Matches if the given method declaration has an explicit "virtual". +/// +/// Given +/// \code +/// class A { +/// public: +/// virtual void x(); +/// }; +/// class B : public A { +/// public: +/// void x(); +/// }; +/// \endcode +/// matches A::x but not B::x +AST_MATCHER(CXXMethodDecl, isVirtualAsWritten) { + return Node.isVirtualAsWritten(); +} + /// \brief Matches if the given method or class declaration is final. /// /// Given: @@ -3482,6 +3984,23 @@ AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) { return Node.isCopyAssignmentOperator(); } +/// \brief Matches if the given method declaration declares a move assignment +/// operator. +/// +/// Given +/// \code +/// struct A { +/// A &operator=(const A &); +/// A &operator=(A &&); +/// }; +/// \endcode +/// +/// cxxMethodDecl(isMoveAssignmentOperator()) matches the second method but not +/// the first one. +AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator) { + return Node.isMoveAssignmentOperator(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given @@ -3500,6 +4019,21 @@ AST_MATCHER(CXXMethodDecl, isOverride) { return Node.size_overridden_methods() > 0 || Node.hasAttr(); } +/// \brief Matches method declarations that are user-provided. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(const S &) = default; // #2 +/// S(S &&) = delete; // #3 +/// }; +/// \endcode +/// cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. +AST_MATCHER(CXXMethodDecl, isUserProvided) { + return Node.isUserProvided(); +} + /// \brief Matches member expressions that are called with '->' as opposed /// to '.'. /// @@ -3533,6 +4067,34 @@ AST_MATCHER(QualType, isInteger) { return Node->isIntegerType(); } +/// \brief Matches QualType nodes that are of unsigned integer type. +/// +/// Given +/// \code +/// void a(int); +/// void b(unsigned long); +/// void c(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isInteger()))) +/// matches "b(unsigned long)", but not "a(int)" and "c(double)". +AST_MATCHER(QualType, isUnsignedInteger) { + return Node->isUnsignedIntegerType(); +} + +/// \brief Matches QualType nodes that are of signed integer type. +/// +/// Given +/// \code +/// void a(int); +/// void b(unsigned long); +/// void c(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isInteger()))) +/// matches "a(int)", but not "b(unsigned long)" and "c(double)". +AST_MATCHER(QualType, isSignedInteger) { + return Node->isSignedIntegerType(); +} + /// \brief Matches QualType nodes that are of character type. /// /// Given @@ -3547,6 +4109,26 @@ AST_MATCHER(QualType, isAnyCharacter) { return Node->isAnyCharacterType(); } +/// \brief Matches QualType nodes that are of any pointer type; this includes +/// the Objective-C object pointer type, which is different despite being +/// syntactically similar. +/// +/// Given +/// \code +/// int *i = nullptr; +/// +/// @interface Foo +/// @end +/// Foo *f; +/// +/// int j; +/// \endcode +/// varDecl(hasType(isAnyPointer())) +/// matches "int *i" and "Foo *f", but not "int j". +AST_MATCHER(QualType, isAnyPointer) { + return Node->isAnyPointerType(); +} + /// \brief Matches QualType nodes that are const-qualified, i.e., that /// include "top-level" const. /// @@ -3822,6 +4404,19 @@ AST_TYPE_MATCHER(ArrayType, arrayType); /// matches "_Complex float f" AST_TYPE_MATCHER(ComplexType, complexType); +/// \brief Matches any real floating-point type (float, double, long double). +/// +/// Given +/// \code +/// int i; +/// float f; +/// \endcode +/// realFloatingPointType() +/// matches "float f" but not "int i" +AST_MATCHER(Type, realFloatingPointType) { + return Node.isRealFloatingType(); +} + /// \brief Matches arrays and C99 complex types that have a specific element /// type. /// @@ -3853,18 +4448,26 @@ AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement, /// matches "int a[2]" AST_TYPE_MATCHER(ConstantArrayType, constantArrayType); -/// \brief Matches \c ConstantArrayType nodes that have the specified size. +/// \brief Matches nodes that have the specified size. /// /// Given /// \code /// int a[42]; /// int b[2 * 21]; /// int c[41], d[43]; +/// char *s = "abcd"; +/// wchar_t *ws = L"abcd"; +/// char *w = "a"; /// \endcode /// constantArrayType(hasSize(42)) /// matches "int a[42]" and "int b[2 * 21]" -AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) { - return Node.getSize() == N; +/// stringLiteral(hasSize(4)) +/// matches "abcd", L"abcd" +AST_POLYMORPHIC_MATCHER_P(hasSize, + AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType, + StringLiteral), + unsigned, N) { + return internal::HasSizeMatcher::hasSize(Node, N); } /// \brief Matches C++ arrays whose size is a value-dependent expression. @@ -3988,6 +4591,18 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, /// matches "int (*f)(int)" and the type of "g". AST_TYPE_MATCHER(FunctionType, functionType); +/// \brief Matches \c FunctionProtoType nodes. +/// +/// Given +/// \code +/// int (*f)(int); +/// void g(); +/// \endcode +/// functionProtoType() +/// matches "int (*f)(int)" and the type of "g" in C++ mode. +/// In C mode, "g" is not matched because it does not contain a prototype. +AST_TYPE_MATCHER(FunctionProtoType, functionProtoType); + /// \brief Matches \c ParenType nodes. /// /// Given @@ -4143,6 +4758,21 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee, /// matches "typedef int X" AST_TYPE_MATCHER(TypedefType, typedefType); +/// \brief Matches enum types. +/// +/// Given +/// \code +/// enum C { Green }; +/// enum class S { Red }; +/// +/// C c; +/// S s; +/// \endcode +// +/// \c enumType() matches the type of the variable declarations of both \c c and +/// \c s. +AST_TYPE_MATCHER(EnumType, enumType); + /// \brief Matches template specialization types. /// /// Given @@ -4563,6 +5193,23 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) { return Node.isDefaultConstructor(); } +/// \brief Matches constructors that delegate to another constructor. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(int) {} // #2 +/// S(S &&) : S() {} // #3 +/// }; +/// S::S() : S(0) {} // #4 +/// \endcode +/// cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not +/// #1 or #2. +AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) { + return Node.isDelegatingConstructor(); +} + /// \brief Matches constructor and conversion declarations that are marked with /// the explicit keyword. /// @@ -4655,6 +5302,24 @@ AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { return false; } +/// \brief Matches the return value expression of a return statement +/// +/// Given +/// \code +/// return a + b; +/// \endcode +/// hasReturnValue(binaryOperator()) +/// matches 'return a + b' +/// with binaryOperator() +/// matching 'a + b' +AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher, + InnerMatcher) { + if (const auto *RetValue = Node.getRetValue()) + return InnerMatcher.matches(*RetValue, Finder, Builder); + return false; +} + + /// \brief Matches CUDA kernel call expression. /// /// Example matches, @@ -4665,6 +5330,66 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CUDAKernelCallExpr> cudaKernelCallExpr; + +/// \brief Matches expressions that resolve to a null pointer constant, such as +/// GNU's __null, C++11's nullptr, or C's NULL macro. +/// +/// Given: +/// \code +/// void *v1 = NULL; +/// void *v2 = nullptr; +/// void *v3 = __null; // GNU extension +/// char *cp = (char *)0; +/// int *ip = 0; +/// int i = 0; +/// \endcode +/// expr(nullPointerConstant()) +/// matches the initializer for v1, v2, v3, cp, and ip. Does not match the +/// initializer for i. +AST_MATCHER_FUNCTION(internal::Matcher, nullPointerConstant) { + return anyOf( + gnuNullExpr(), cxxNullPtrLiteralExpr(), + integerLiteral(equals(0), hasParent(expr(hasType(pointerType()))))); +} + +/// \brief Matches declaration of the function the statemenet belongs to +/// +/// Given: +/// \code +/// F& operator=(const F& o) { +/// std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; }); +/// return *this; +/// } +/// \endcode +/// returnStmt(forFunction(hasName("operator="))) +/// matches 'return *this' +/// but does match 'return > 0' +AST_MATCHER_P(Stmt, forFunction, internal::Matcher, + InnerMatcher) { + const auto &Parents = Finder->getASTContext().getParents(Node); + + llvm::SmallVector Stack(Parents.begin(), + Parents.end()); + while(!Stack.empty()) { + const auto &CurNode = Stack.back(); + Stack.pop_back(); + if(const auto *FuncDeclNode = CurNode.get()) { + if(InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) { + return true; + } + } else if(const auto *LambdaExprNode = CurNode.get()) { + if(InnerMatcher.matches(*LambdaExprNode->getCallOperator(), + Finder, Builder)) { + return true; + } + } else { + for(const auto &Parent: Finder->getASTContext().getParents(CurNode)) + Stack.push_back(Parent); + } + } + return false; +} + } // end namespace ast_matchers } // end namespace clang diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index 1d1d7952c16..c2c01fbd78e 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -46,8 +46,9 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/Type.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/VariadicFunction.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/ManagedStatic.h" #include #include @@ -60,6 +61,62 @@ class BoundNodes; namespace internal { +/// \brief Variadic function object. +/// +/// Most of the functions below that use VariadicFunction could be implemented +/// using plain C++11 variadic functions, but the function object allows us to +/// capture it on the dynamic matcher registry. +template )> +struct VariadicFunction { + ResultT operator()() const { return Func(None); } + + template + ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const { + return Execute(Arg1, static_cast(Args)...); + } + + // We also allow calls with an already created array, in case the caller + // already had it. + ResultT operator()(ArrayRef Args) const { + SmallVector InnerArgs; + for (const ArgT &Arg : Args) + InnerArgs.push_back(&Arg); + return Func(InnerArgs); + } + +private: + // Trampoline function to allow for implicit conversions to take place + // before we make the array. + template ResultT Execute(const ArgsT &... Args) const { + const ArgT *const ArgsArray[] = {&Args...}; + return Func(ArrayRef(ArgsArray, sizeof...(ArgsT))); + } +}; + +/// \brief Unifies obtaining the underlying type of a regular node through +/// `getType` and a TypedefNameDecl node through `getUnderlyingType`. +inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); } + +inline QualType getUnderlyingType(const ValueDecl &Node) { + return Node.getType(); +} + +inline QualType getUnderlyingType(const TypedefNameDecl &Node) { + return Node.getUnderlyingType(); +} + +/// \brief Unifies obtaining the FunctionProtoType pointer from both +/// FunctionProtoType and FunctionDecl nodes.. +inline const FunctionProtoType * +getFunctionProtoType(const FunctionProtoType &Node) { + return &Node; +} + +inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) { + return Node.getType()->getAs(); +} + /// \brief Internal version of BoundNodes. Holds all the bound nodes. class BoundNodesMap { public: @@ -420,7 +477,7 @@ class Matcher { template Matcher(const Matcher &Other, typename std::enable_if::value && - !std::is_same::value>::type * = 0) + !std::is_same::value>::type * = nullptr) : Implementation(restrictMatcher(Other.Implementation)) { assert(Implementation.getSupportedKind().isSame( ast_type_traits::ASTNodeKind::getFromNodeKind())); @@ -433,7 +490,7 @@ class Matcher { Matcher(const Matcher &Other, typename std::enable_if< std::is_same::value && - std::is_same::value>::type* = 0) + std::is_same::value>::type* = nullptr) : Implementation(new TypeToQualType(Other)) {} /// \brief Convert \c this into a \c Matcher by applying dyn_cast<> to the @@ -558,32 +615,21 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, return false; } -// Metafunction to determine if type T has a member called -// getDecl. -#if defined(_MSC_VER) && !defined(__clang__) -// For MSVC, we use a weird nonstandard __if_exists statement, as it -// is not standards-conformant enough to properly compile the standard -// code below. (At least up through MSVC 2015 require this workaround) -template struct has_getDecl { - __if_exists(T::getDecl) { - enum { value = 1 }; - } - __if_not_exists(T::getDecl) { - enum { value = 0 }; - } +// Metafunction to determine if type T has a member called getDecl. +template +class has_getDecl { + typedef char yes[1]; + typedef char no[2]; + + template + static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr); + + template + static no& test(...); + +public: + static const bool value = sizeof(test(nullptr)) == sizeof(yes); }; -#else -// There is a default template inheriting from "false_type". Then, a -// partial specialization inherits from "true_type". However, this -// specialization will only exist when the call to getDecl() isn't an -// error -- it vanishes by SFINAE when the member doesn't exist. -template struct type_sink_to_void { typedef void type; }; -template struct has_getDecl : std::false_type {}; -template -struct has_getDecl< - T, typename type_sink_to_void().getDecl())>::type> - : std::true_type {}; -#endif /// \brief Matches overloaded operators with a specific name. /// @@ -626,10 +672,10 @@ class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface { /// \brief Matches named declarations with a specific name. /// -/// See \c hasName() in ASTMatchers.h for details. +/// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details. class HasNameMatcher : public SingleNodeMatcherInterface { public: - explicit HasNameMatcher(StringRef Name); + explicit HasNameMatcher(std::vector Names); bool matchesNode(const NamedDecl &Node) const override; @@ -640,17 +686,29 @@ class HasNameMatcher : public SingleNodeMatcherInterface { /// matches. bool matchesNodeUnqualified(const NamedDecl &Node) const; + /// \brief Full match routine + /// + /// Fast implementation for the simple case of a named declaration at + /// namespace or RecordDecl scope. + /// It is slower than matchesNodeUnqualified, but faster than + /// matchesNodeFullSlow. + bool matchesNodeFullFast(const NamedDecl &Node) const; + /// \brief Full match routine /// /// It generates the fully qualified name of the declaration (which is /// expensive) before trying to match. /// It is slower but simple and works on all cases. - bool matchesNodeFull(const NamedDecl &Node) const; + bool matchesNodeFullSlow(const NamedDecl &Node) const; const bool UseUnqualifiedMatch; - const std::string Name; + const std::vector Names; }; +/// \brief Trampoline function to use VariadicFunction<> to construct a +/// HasNameMatcher. +Matcher hasAnyNameFunc(ArrayRef NameRefs); + /// \brief Matches declarations for QualType and CallExpr. /// /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but @@ -737,6 +795,14 @@ class HasDeclarationMatcher : public WrapperMatcherInterface { return matchesDecl(Node.getMemberDecl(), Finder, Builder); } + /// \brief Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns + /// whether the inner matcher matches on it. + bool matchesSpecialized(const AddrLabelExpr &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return matchesDecl(Node.getLabel(), Finder, Builder); + } + /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node /// is \c NULL. bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder, @@ -942,8 +1008,8 @@ typedef TypeList HasDeclarationSupportedTypes; @@ -1110,8 +1176,6 @@ class BindableMatcher : public Matcher { /// ChildT must be an AST base type. template class HasMatcher : public WrapperMatcherInterface { - static_assert(IsBaseType::value, - "has only accepts base type matcher"); public: explicit HasMatcher(const Matcher &ChildMatcher) @@ -1119,10 +1183,9 @@ class HasMatcher : public WrapperMatcherInterface { bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesChildOf( - Node, this->InnerMatcher, Builder, - ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, - ASTMatchFinder::BK_First); + return Finder->matchesChildOf(Node, this->InnerMatcher, Builder, + ASTMatchFinder::TK_AsIs, + ASTMatchFinder::BK_First); } }; @@ -1385,9 +1448,8 @@ inline bool ValueEqualsMatcher::matchesNode( /// casted to CXXRecordDecl and all given matchers match. template class VariadicDynCastAllOfMatcher - : public llvm::VariadicFunction< - BindableMatcher, Matcher, - makeDynCastAllOfComposite > { + : public VariadicFunction, Matcher, + makeDynCastAllOfComposite> { public: VariadicDynCastAllOfMatcher() {} }; @@ -1403,9 +1465,9 @@ class VariadicDynCastAllOfMatcher /// \c Matcher. /// The returned matcher matches if all given matchers match. template -class VariadicAllOfMatcher : public llvm::VariadicFunction< - BindableMatcher, Matcher, - makeAllOfComposite > { +class VariadicAllOfMatcher + : public VariadicFunction, Matcher, + makeAllOfComposite> { public: VariadicAllOfMatcher() {} }; @@ -1526,8 +1588,8 @@ class TypeTraversePolymorphicMatcher { new MatcherImpl(InnerMatcher, Getter::value())); } - struct Func : public llvm::VariadicFunction, - &Self::create> { + struct Func + : public VariadicFunction, &Self::create> { Func() {} }; @@ -1584,8 +1646,60 @@ struct NotEqualsBoundNodePredicate { ast_type_traits::DynTypedNode Node; }; +template +struct GetBodyMatcher { + static const Stmt *get(const Ty &Node) { + return Node.getBody(); + } +}; + +template <> +inline const Stmt *GetBodyMatcher::get(const FunctionDecl &Node) { + return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr; +} + +template +struct HasSizeMatcher { + static bool hasSize(const Ty &Node, unsigned int N) { + return Node.getSize() == N; + } +}; + +template <> +inline bool HasSizeMatcher::hasSize( + const StringLiteral &Node, unsigned int N) { + return Node.getLength() == N; +} + +template +struct GetSourceExpressionMatcher { + static const Expr *get(const Ty &Node) { + return Node.getSubExpr(); + } +}; + +template <> +inline const Expr *GetSourceExpressionMatcher::get( + const OpaqueValueExpr &Node) { + return Node.getSourceExpr(); +} + +template +struct CompoundStmtMatcher { + static const CompoundStmt *get(const Ty &Node) { + return &Node; + } +}; + +template <> +inline const CompoundStmt * +CompoundStmtMatcher::get(const StmtExpr &Node) { + return Node.getSubStmt(); +} + + } // end namespace internal } // end namespace ast_matchers } // end namespace clang -#endif +#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h index 4471311a339..74803a295d7 100644 --- a/include/clang/Analysis/Analyses/FormatString.h +++ b/include/clang/Analysis/Analyses/FormatString.h @@ -210,11 +210,16 @@ class ConversionSpecifier { unsigned getLength() const { return EndScanList ? EndScanList - Position : 1; } + void setEndScanList(const char *pos) { EndScanList = pos; } bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) || kind == FreeBSDrArg || kind == FreeBSDyArg; } bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } + bool isDoubleArg() const { + return kind >= DoubleArgBeg && kind <= DoubleArgEnd; + } + const char *toString() const; bool isPrintfKind() const { return IsPrintf; } @@ -413,11 +418,6 @@ class PrintfConversionSpecifier : bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; } bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } - unsigned getLength() const { - // Conversion specifiers currently only are represented by - // single characters, but we be flexible. - return 1; - } static bool classof(const analyze_format_string::ConversionSpecifier *CS) { return CS->isPrintfKind(); @@ -546,8 +546,6 @@ class ScanfConversionSpecifier : ScanfConversionSpecifier(const char *pos, Kind k) : ConversionSpecifier(false, pos, k) {} - void setEndScanList(const char *pos) { EndScanList = pos; } - static bool classof(const analyze_format_string::ConversionSpecifier *CS) { return !CS->isPrintfKind(); } diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index 4d3402f8c00..6ea93653b91 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -58,18 +58,15 @@ class MemRegionRef { llvm::BumpPtrAllocator *Allocator; }; - } // end namespace til } // end namespace threadSafety } // end namespace clang - inline void *operator new(size_t Sz, clang::threadSafety::til::MemRegionRef &R) { return R.allocate(Sz); } - namespace clang { namespace threadSafety { @@ -80,7 +77,6 @@ using clang::SourceLocation; namespace til { - // A simple fixed size array class that does not manage its own memory, // suitable for use with bump pointer allocation. template class SimpleArray { @@ -117,7 +113,6 @@ template class SimpleArray { Data = A.allocateT(Ncp); Capacity = Ncp; memcpy(Data, Odata, sizeof(T) * Size); - return; } // Reserve space for at least N more items. @@ -221,10 +216,8 @@ template class SimpleArray { size_t Capacity; }; - } // end namespace til - // A copy on write vector. // The vector can be in one of three states: // * invalid -- no operations are permitted. @@ -346,13 +339,11 @@ class CopyOnWriteVector { VectorData *Data; }; - inline std::ostream& operator<<(std::ostream& ss, const StringRef str) { return ss.write(str.data(), str.size()); } - } // end namespace threadSafety } // end namespace clang -#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H +#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 931190e43a6..4324a0352e3 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -201,6 +201,10 @@ class AnalysisDeclContext { } return static_cast(data); } + + /// Returns true if the root namespace of the given declaration is the 'std' + /// C++ namespace. + static bool isInStdNamespace(const Decl *D); private: ManagedAnalysis *&getAnalysisImpl(const void* tag); diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 6d816fd733e..5045194ef86 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -595,6 +595,13 @@ class CallEnter : public ProgramPoint { return static_cast(getData2()); } + /// Returns the entry block in the CFG for the entered function. + const CFGBlock *getEntry() const { + const StackFrameContext *CalleeCtx = getCalleeContext(); + const CFG *CalleeCFG = CalleeCtx->getCFG(); + return &(CalleeCFG->getEntry()); + } + private: friend class ProgramPoint; CallEnter() {} diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h index 8dd75660c67..63df61bedbc 100644 --- a/include/clang/Basic/AddressSpaces.h +++ b/include/clang/Basic/AddressSpaces.h @@ -25,7 +25,7 @@ namespace LangAS { /// This uses a high starting offset so as not to conflict with any address /// space used by a target. enum ID { - Offset = 0xFFFF00, + Offset = 0x7FFF00, opencl_global = Offset, opencl_local, diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index d5ba7226164..7da1efe5ff4 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -82,6 +82,8 @@ def NormalVar : SubsetSubjectgetKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && S->getKind() != Decl::NonTypeTemplateParm}]>; +def NonParmVar : SubsetSubjectgetKind() != Decl::ParmVar}]>; def NonBitField : SubsetSubjectisBitField()}]>; @@ -239,6 +241,8 @@ def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; def COnly : LangOpt<"CPlusPlus", 1>; +def OpenCL : LangOpt<"OpenCL">; +def RenderScript : LangOpt<"RenderScript">; // Defines targets for target-specific attributes. The list of strings should // specify architectures for which the target applies, based off the ArchType @@ -252,6 +256,7 @@ def TargetARM : TargetArch<["arm", "thumb"]>; def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; +def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> { let OSes = ["Win32"]; } @@ -310,6 +315,9 @@ class TypeAttr : Attr { let ASTNode = 0; } +/// A stmt attribute is not processed on a declaration or a type. +class StmtAttr : Attr; + /// An inheritable attribute is inherited by later redeclarations. class InheritableAttr : Attr; @@ -337,6 +345,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// An attribute which changes the ABI rules for a specific parameter. +class ParameterABIAttr : InheritableParamAttr { + let Subjects = SubjectList<[ParmVar]>; +} + /// An ignored attribute, which we parse but discard with no checking. class IgnoredAttr : Attr { let Ignored = 1; @@ -349,6 +362,14 @@ class IgnoredAttr : Attr { // Attributes begin here // +def AbiTag : Attr { + let Spellings = [GCC<"abi_tag">]; + let Args = [VariadicStringArgument<"Tags">]; + let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag, + "ExpectedStructClassVariableFunctionOrInlineNamespace">; + let Documentation = [AbiTagsDocs]; +} + def AddressSpace : TypeAttr { let Spellings = [GNU<"address_space">]; let Args = [IntArgument<"AddressSpace">]; @@ -407,6 +428,22 @@ def AlwaysInline : InheritableAttr { let Documentation = [Undocumented]; } +def XRayInstrument : InheritableAttr { + let Spellings = [GNU<"xray_always_instrument">, + CXX11<"clang", "xray_always_instrument">, + GNU<"xray_never_instrument">, + CXX11<"clang", "xray_never_instrument">]; + let Subjects = SubjectList<[CXXMethod, ObjCMethod, Function], WarnDiag, + "ExpectedFunctionOrMethod">; + let Accessors = [Accessor<"alwaysXRayInstrument", + [GNU<"xray_always_instrument">, + CXX11<"clang", "xray_always_instrument">]>, + Accessor<"neverXRayInstrument", + [GNU<"xray_never_instrument">, + CXX11<"clang", "xray_never_instrument">]>]; + let Documentation = [XRayDocs]; +} + def TLSModel : InheritableAttr { let Spellings = [GCC<"tls_model">]; let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">; @@ -426,8 +463,8 @@ def Annotate : InheritableParamAttr { } def ARMInterrupt : InheritableAttr, TargetSpecificAttr { - // NOTE: If you add any additional spellings, MSP430Interrupt's and - // MipsInterrupt's spellings must match. + // NOTE: If you add any additional spellings, MSP430Interrupt's, + // MipsInterrupt's and AnyX86Interrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [EnumArgument<"Interrupt", "InterruptType", ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], @@ -449,17 +486,18 @@ def Availability : InheritableAttr { let Spellings = [GNU<"availability">]; let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, - BoolArgument<"unavailable">, StringArgument<"message">]; + BoolArgument<"unavailable">, StringArgument<"message">, + BoolArgument<"strict">, StringArgument<"replacement">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) .Case("android", "Android") .Case("ios", "iOS") - .Case("macosx", "OS X") + .Case("macos", "macOS") .Case("tvos", "tvOS") .Case("watchos", "watchOS") .Case("ios_app_extension", "iOS (App Extension)") - .Case("macosx_app_extension", "OS X (App Extension)") + .Case("macos_app_extension", "macOS (App Extension)") .Case("tvos_app_extension", "tvOS (App Extension)") .Case("watchos_app_extension", "watchOS (App Extension)") .Default(llvm::StringRef()); @@ -654,20 +692,27 @@ def OpenCLKernel : InheritableAttr { let Documentation = [Undocumented]; } +def OpenCLUnrollHint : InheritableAttr { + let Spellings = [GNU<"opencl_unroll_hint">]; + let Args = [UnsignedArgument<"UnrollHint">]; + let Documentation = [OpenCLUnrollHintDocs]; +} + // This attribute is both a type attribute, and a declaration attribute (for // parameter variables). -def OpenCLImageAccess : Attr { +def OpenCLAccess : Attr { let Spellings = [Keyword<"__read_only">, Keyword<"read_only">, Keyword<"__write_only">, Keyword<"write_only">, Keyword<"__read_write">, Keyword<"read_write">]; - let Subjects = SubjectList<[ParmVar], ErrorDiag>; + let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag, + "ExpectedParameterOrTypedef">; let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">, Keyword<"read_only">]>, Accessor<"isReadWrite", [Keyword<"__read_write">, Keyword<"read_write">]>, Accessor<"isWriteOnly", [Keyword<"__write_only">, Keyword<"write_only">]>]; - let Documentation = [Undocumented]; + let Documentation = [OpenCLAccessDocs]; } def OpenCLPrivateAddressSpace : TypeAttr { @@ -695,11 +740,29 @@ def OpenCLGenericAddressSpace : TypeAttr { let Documentation = [OpenCLAddressSpaceGenericDocs]; } +def OpenCLNoSVM : Attr { + let Spellings = [GNU<"nosvm">]; + let Subjects = SubjectList<[Var]>; + let Documentation = [OpenCLNoSVMDocs]; + let LangOpts = [OpenCL]; + let ASTNode = 0; +} + +def RenderScriptKernel : Attr { + let Spellings = [GNU<"kernel">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [RenderScriptKernelAttributeDocs]; + let LangOpts = [RenderScript]; +} + def Deprecated : InheritableAttr { let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, CXX11<"","deprecated", 201309>]; - let Args = [StringArgument<"Message", 1>]; - let Documentation = [Undocumented]; + let Args = [StringArgument<"Message", 1>, + // An optional string argument that enables us to provide a + // Fix-It. + StringArgument<"Replacement", 1>]; + let Documentation = [DeprecatedDocs]; } def Destructor : InheritableAttr { @@ -709,6 +772,12 @@ def Destructor : InheritableAttr { let Documentation = [Undocumented]; } +def EmptyBases : InheritableAttr, TargetSpecificAttr { + let Spellings = [Declspec<"empty_bases">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [EmptyBasesDocs]; +} + def EnableIf : InheritableAttr { let Spellings = [GNU<"enable_if">]; let Subjects = SubjectList<[Function]>; @@ -725,8 +794,9 @@ def ExtVectorType : Attr { let Documentation = [Undocumented]; } -def FallThrough : Attr { - let Spellings = [CXX11<"clang", "fallthrough">]; +def FallThrough : StmtAttr { + let Spellings = [CXX11<"", "fallthrough", 201603>, + CXX11<"clang", "fallthrough">]; // let Subjects = [NullStmt]; let Documentation = [FallthroughDocs]; } @@ -818,12 +888,26 @@ def IBOutletCollection : InheritableAttr { let Documentation = [Undocumented]; } +def IFunc : Attr { + let Spellings = [GCC<"ifunc">]; + let Args = [StringArgument<"Resolver">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [IFuncDocs]; +} + def Restrict : InheritableAttr { let Spellings = [Declspec<"restrict">, GCC<"malloc">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } +def LayoutVersion : InheritableAttr, TargetSpecificAttr { + let Spellings = [Declspec<"layout_version">]; + let Args = [UnsignedArgument<"Version">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [LayoutVersionDocs]; +} + def MaxFieldAlignment : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; @@ -845,8 +929,8 @@ def MSABI : InheritableAttr { } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr { - // NOTE: If you add any additional spellings, ARMInterrupt's and - // MipsInterrupt's spellings must match. + // NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's + // and AnyX86Interrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [UnsignedArgument<"Number">]; let ParseKind = "Interrupt"; @@ -861,8 +945,8 @@ def Mips16 : InheritableAttr, TargetSpecificAttr { } def MipsInterrupt : InheritableAttr, TargetSpecificAttr { - // NOTE: If you add any additional spellings, ARMInterrupt's and - // MSP430Interrupt's spellings must match. + // NOTE: If you add any additional spellings, ARMInterrupt's, + // MSP430Interrupt's and AnyX86Interrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Subjects = SubjectList<[Function]>; let Args = [EnumArgument<"Interrupt", "InterruptType", @@ -878,6 +962,8 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr { def Mode : Attr { let Spellings = [GCC<"mode">]; + let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag, + "ExpectedVariableEnumFieldOrTypedef">; let Args = [IdentifierArgument<"Mode">]; let Documentation = [Undocumented]; } @@ -927,7 +1013,9 @@ def NoCommon : InheritableAttr { def NoDebug : InheritableAttr { let Spellings = [GCC<"nodebug">]; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar], WarnDiag, + "ExpectedVariableOrFunction">; + let Documentation = [NoDebugDocs]; } def NoDuplicate : InheritableAttr { @@ -1202,6 +1290,12 @@ def ObjCRuntimeName : Attr { let Documentation = [ObjCRuntimeNameDocs]; } +def ObjCRuntimeVisible : Attr { + let Spellings = [GNU<"objc_runtime_visible">]; + let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; + let Documentation = [ObjCRuntimeVisibleDocs]; +} + def ObjCBoxable : Attr { let Spellings = [GNU<"objc_boxable">]; let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">; @@ -1325,6 +1419,27 @@ def StdCall : InheritableAttr { let Documentation = [StdCallDocs]; } +def SwiftCall : InheritableAttr { + let Spellings = [GCC<"swiftcall">]; +// let Subjects = SubjectList<[Function]>; + let Documentation = [SwiftCallDocs]; +} + +def SwiftContext : ParameterABIAttr { + let Spellings = [GCC<"swift_context">]; + let Documentation = [SwiftContextDocs]; +} + +def SwiftErrorResult : ParameterABIAttr { + let Spellings = [GCC<"swift_error_result">]; + let Documentation = [SwiftErrorResultDocs]; +} + +def SwiftIndirectResult : ParameterABIAttr { + let Spellings = [GCC<"swift_indirect_result">]; + let Documentation = [SwiftIndirectResultDocs]; +} + def SysVABI : InheritableAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; @@ -1351,6 +1466,16 @@ def Pascal : InheritableAttr { let Documentation = [Undocumented]; } +def PreserveMost : InheritableAttr { + let Spellings = [GNU<"preserve_most">]; + let Documentation = [PreserveMostDocs]; +} + +def PreserveAll : InheritableAttr { + let Spellings = [GNU<"preserve_all">]; + let Documentation = [PreserveAllDocs]; +} + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; @@ -1436,11 +1561,11 @@ def ObjCRequiresPropertyDefs : InheritableAttr { } def Unused : InheritableAttr { - let Spellings = [GCC<"unused">]; - let Subjects = SubjectList<[Var, ObjCIvar, Type, Label, Field, ObjCMethod, - FunctionLike], WarnDiag, - "ExpectedVariableFunctionOrLabel">; - let Documentation = [Undocumented]; + let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">]; + let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, + Field, ObjCMethod, FunctionLike], WarnDiag, + "ExpectedForMaybeUnused">; + let Documentation = [WarnMaybeUnusedDocs]; } def Used : InheritableAttr { @@ -1501,11 +1626,12 @@ def WarnUnused : InheritableAttr { } def WarnUnusedResult : InheritableAttr { - let Spellings = [GCC<"warn_unused_result">, - CXX11<"clang", "warn_unused_result">]; - let Subjects = SubjectList<[ObjCMethod, CXXRecord, FunctionLike], WarnDiag, - "ExpectedFunctionMethodOrClass">; - let Documentation = [Undocumented]; + let Spellings = [CXX11<"", "nodiscard", 201603>, + CXX11<"clang", "warn_unused_result">, + GCC<"warn_unused_result">]; + let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike], + WarnDiag, "ExpectedFunctionMethodEnumOrClass">; + let Documentation = [WarnUnusedResultsDocs]; } def Weak : InheritableAttr { @@ -1527,6 +1653,22 @@ def WeakRef : InheritableAttr { let Documentation = [Undocumented]; } +def LTOVisibilityPublic : InheritableAttr { + let Spellings = [CXX11<"clang", "lto_visibility_public">]; + let Subjects = SubjectList<[Record]>; + let Documentation = [LTOVisibilityDocs]; +} + +def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr { + // NOTE: If you add any additional spellings, ARMInterrupt's, + // MSP430Interrupt's and MipsInterrupt's spellings must match. + let Spellings = [GNU<"interrupt">]; + let Subjects = SubjectList<[HasFunctionProto]>; + let ParseKind = "Interrupt"; + let HasCustomParsing = 1; + let Documentation = [AnyX86InterruptDocs]; +} + def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr { let Spellings = [GNU<"force_align_arg_pointer">]; // Technically, this appertains to a FunctionDecl, but the target-specific @@ -1945,14 +2087,14 @@ def MSStruct : InheritableAttr { def DLLExport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllexport">, GCC<"dllexport">]; - let Subjects = SubjectList<[Function, Var, CXXRecord]>; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; + let Documentation = [DLLExportDocs]; } def DLLImport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; - let Subjects = SubjectList<[Function, Var, CXXRecord]>; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; + let Documentation = [DLLImportDocs]; } def SelectAny : InheritableAttr { @@ -2055,10 +2197,6 @@ def InitSeg : Attr { }]; } -def Unaligned : IgnoredAttr { - let Spellings = [Keyword<"__unaligned">]; -} - def LoopHint : Attr { /// #pragma clang loop