diff --git a/CMakeLists.txt b/CMakeLists.txt index ab70f1dab61f..2c54e751e91e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) option(LLVM_FORCE_USE_OLD_HOST_TOOLCHAIN "Set to ON to force using an old, unsupported host toolchain." OFF) + option(CLANG_ENABLE_BOOTSTRAP "Generate the clang bootstrap target" OFF) include(AddLLVM) include(TableGen) @@ -115,6 +116,19 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} ) if(LLVM_INCLUDE_TESTS) + set(Python_ADDITIONAL_VERSIONS 2.7) + include(FindPythonInterp) + if(NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR +"Unable to find Python interpreter, required for builds and testing. + +Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") + endif() + + if( ${PYTHON_VERSION_STRING} VERSION_LESS 2.7 ) + message(FATAL_ERROR "Python 2.7 or newer is required") + endif() + # Check prebuilt llvm/utils. if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX} AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/count${CMAKE_EXECUTABLE_SUFFIX} @@ -167,7 +181,7 @@ else() set(BACKEND_PACKAGE_STRING "${PACKAGE_STRING}") endif() -find_package(LibXml2) +find_package(LibXml2 2.5.3 QUIET) if (LIBXML2_FOUND) set(CLANG_HAVE_LIBXML 1) endif() @@ -182,7 +196,7 @@ set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." ) set(DEFAULT_SYSROOT "" CACHE PATH "Default to all compiler invocations for --sysroot=." ) -set(CLANG_DEFAULT_OPENMP_RUNTIME "libgomp" CACHE STRING +set(CLANG_DEFAULT_OPENMP_RUNTIME "libomp" CACHE STRING "Default OpenMP runtime used by -fopenmp.") set(CLANG_VENDOR "" CACHE STRING @@ -252,7 +266,10 @@ configure_file( # Add appropriate flags for GCC if (LLVM_COMPILER_IS_GCC_COMPATIBLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual") + if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") + endif () # Enable -pedantic for Clang even if it's not enabled for LLVM. if (NOT LLVM_ENABLE_PEDANTIC) @@ -331,9 +348,13 @@ macro(set_clang_windows_version_resource_properties name) 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}) @@ -358,7 +379,7 @@ macro(add_clang_library name) set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON) if(headers OR tds) - set(srcs ${headers} ${tds}) + set(srcs ${headers} ${tds}) endif() endif() endif(MSVC_IDE OR XCODE) @@ -369,17 +390,29 @@ macro(add_clang_library name) ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args. ) endif() - llvm_add_library(${name} ${ARG_UNPARSED_ARGUMENTS} ${srcs}) + 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() @@ -397,6 +430,12 @@ macro(add_clang_executable name) 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() + set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(BEFORE @@ -423,13 +462,28 @@ 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 - DESTINATION include + 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_ENABLE_ARCMT "Build ARCMT." ON) @@ -467,6 +521,10 @@ set(LIBCLANG_LIBRARY_VERSION "Version number that will be placed into the libclang library , in the form XX.YY") mark_as_advanced(CLANG_EXECUTABLE_VERSION LIBCLANG_LIBRARY_VERSION) +option(CLANG_INCLUDE_TESTS + "Generate build targets for the Clang unit tests." + ${LLVM_INCLUDE_TESTS}) + add_subdirectory(utils/TableGen) add_subdirectory(include) @@ -487,10 +545,6 @@ else() endif() add_subdirectory(examples) -option(CLANG_INCLUDE_TESTS - "Generate build targets for the Clang unit tests." - ${LLVM_INCLUDE_TESTS}) - if( CLANG_INCLUDE_TESTS ) if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include/gtest/gtest.h) add_subdirectory(unittests) @@ -516,6 +570,7 @@ if( CLANG_INCLUDE_TESTS ) ARGS ${LLVM_LIT_EXTRA_ARGS} ) endif() + add_subdirectory(utils/perf-training) endif() option(CLANG_INCLUDE_DOCS "Generate build targets for the Clang docs." @@ -527,7 +582,8 @@ endif() set(CLANG_ORDER_FILE "" CACHE FILEPATH "Order file to use when compiling clang in order to improve startup time.") -if (CLANG_BUILT_STANDALONE) +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. @@ -551,3 +607,153 @@ if (CLANG_BUILT_STANDALONE) ${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) + 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) + endif() + + if(NOT CLANG_STAGE) + set(CLANG_STAGE stage1) + message(STATUS "Setting current clang stage to: ${CLANG_STAGE}") + endif() + + string(REGEX MATCH "stage([0-9]*)" MATCHED_STAGE "${CLANG_STAGE}") + if(MATCHED_STAGE) + math(EXPR STAGE_NUM "${MATCHED_STAGE} + 1") + set(NEXT_CLANG_STAGE stage${STAGE_NUM}) + else() + set(NEXT_CLANG_STAGE bootstrap) + endif() + message(STATUS "Setting next clang stage to: ${NEXT_CLANG_STAGE}") + + + 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) + endif() + + add_custom_target(${NEXT_CLANG_STAGE}-clear + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-cleared + ) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-cleared + DEPENDS clang ${LTO_DEP} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${STAMP_DIR} + COMMENT "Clobberring ${NEXT_CLANG_STAGE} build and stamp directories" + ) + + if(CMAKE_VERBOSE_MAKEFILE) + set(verbose -DCMAKE_VERBOSE_MAKEFILE=On) + endif() + + set(BOOTSTRAP_DEFAULT_PASSTHROUGH + PACKAGE_VERSION + LLVM_VERSION_MAJOR + LLVM_VERSION_MINOR + LLVM_VERSION_PATCH + LLVM_VERSION_SUFFIX + CLANG_REPOSITORY_STRING + CMAKE_MAKE_PROGRAM) + + if(TARGET compiler-rt) + set(RUNTIME_DEP compiler-rt) + endif() + + # Find all variables that start with BOOTSTRAP_ and populate a variable with + # them. + get_cmake_property(variableNames VARIABLES) + foreach(variableName ${variableNames}) + if(variableName MATCHES "^BOOTSTRAP_") + string(SUBSTRING ${variableName} 10 -1 varName) + string(REPLACE ";" "\;" value "${${variableName}}") + list(APPEND PASSTHROUGH_VARIABLES + -D${varName}=${value}) + endif() + endforeach() + + # Populate the passthrough variables + foreach(variableName ${CLANG_BOOTSTRAP_PASSTHROUGH} ${BOOTSTRAP_DEFAULT_PASSTHROUGH}) + if(${variableName}) + string(REPLACE ";" "\;" value ${${variableName}}) + list(APPEND PASSTHROUGH_VARIABLES + -D${variableName}=${value}) + endif() + endforeach() + + ExternalProject_Add(${NEXT_CLANG_STAGE} + DEPENDS clang ${LTO_DEP} ${RUNTIME_DEP} + PREFIX ${NEXT_CLANG_STAGE} + SOURCE_DIR ${CMAKE_SOURCE_DIR} + STAMP_DIR ${STAMP_DIR} + BINARY_DIR ${BINARY_DIR} + ${cmake_3_1_EXCLUDE_FROM_ALL} + 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 + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + ${CLANG_BOOTSTRAP_CMAKE_ARGS} + ${PASSTHROUGH_VARIABLES} + -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++ + -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang + -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang + -DCLANG_STAGE=${NEXT_CLANG_STAGE} + ${LTO_LIBRARY} ${LTO_AR} ${LTO_RANLIB} ${verbose} + INSTALL_COMMAND "" + STEP_TARGETS configure build + ${cmake_3_4_USES_TERMINAL_OPTIONS} + ) + + # 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 + COMMENT "Performing install step for '${NEXT_CLANG_STAGE}'" + DEPENDEES build + ${cmake_3_4_USES_TERMINAL} + ) + ExternalProject_Add_StepTargets(${NEXT_CLANG_STAGE} really-install) + add_custom_target(${NEXT_CLANG_STAGE}-install DEPENDS ${NEXT_CLANG_STAGE}-really-install) + + if(NOT CLANG_BOOTSTRAP_TARGETS) + set(CLANG_BOOTSTRAP_TARGETS check-llvm check-clang check-all) + endif() + foreach(target ${CLANG_BOOTSTRAP_TARGETS}) + # exclude from main target + 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} + COMMENT "Performing ${target} for '${NEXT_CLANG_STAGE}'" + DEPENDEES configure + ${cmake_3_4_USES_TERMINAL} + ) + + if(target MATCHES "^stage[0-9]*") + add_custom_target(${target} DEPENDS ${NEXT_CLANG_STAGE}-${target}) + endif() + + ExternalProject_Add_StepTargets(${NEXT_CLANG_STAGE} ${target}) + endforeach() +endif() diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index 905303fe11c2..971fe9bde10a 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -33,22 +33,22 @@ N: Reid Kleckner E: rnk@google.com D: Microsoft C++ ABI compatibility and general Windows support +N: Manuel Klimek +E: klimek@google.com +D: AST matchers, LibTooling + N: Anton Korobeynikov E: anton@korobeynikov.info D: Exception handling, Windows codegen, ARM EABI -N: Ted Kremenek -E: kremenek@apple.com +N: Anna Zaks +E: ganna@apple.com D: Clang Static Analyzer N: John McCall E: rjmccall@apple.com D: Clang LLVM IR generation -N: Chad Rosier -E: mcrosier@codeaurora.org -D: Compiler driver - N: Richard Smith E: richard@metafoo.co.uk D: All parts of Clang not covered by someone else diff --git a/INSTALL.txt b/INSTALL.txt index bd2f4fe37096..fc9bd4620b90 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -44,6 +44,5 @@ From inside the Clang build directory, run 'make install' to install the Clang compiler and header files into the prefix directory selected when LLVM was configured. -The Clang compiler is available as 'clang' and 'clang++'. It supports a gcc like command line -interface. See the man page for clang (installed into $prefix/share/man/man1) -for more information. +The Clang compiler is available as 'clang' and 'clang++'. It supports a gcc like +command line interface. See the man page for clang for more information. diff --git a/Makefile b/Makefile index bbc521f4c0e5..9497b0a42198 100644 --- a/Makefile +++ b/Makefile @@ -67,8 +67,11 @@ endif # http://gcc.gnu.org/PR41874 # http://gcc.gnu.org/PR41838 # -# We can revisit this when LLVM/Clang support it. +# 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 diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index f5caca8572cb..e4b38769b77d 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -1100,6 +1100,11 @@ def __repr__(self): CursorKind.CUDAHOST_ATTR = CursorKind(415) CursorKind.CUDASHARED_ATTR = CursorKind(416) +CursorKind.VISIBILITY_ATTR = CursorKind(417) + +CursorKind.DLLEXPORT_ATTR = CursorKind(418) +CursorKind.DLLIMPORT_ATTR = CursorKind(419) + ### # Preprocessing CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500) @@ -1112,7 +1117,8 @@ def __repr__(self): # A module import declaration. CursorKind.MODULE_IMPORT_DECL = CursorKind(600) - +# A type alias template declaration +CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601) ### Template Argument Kinds ### class TemplateArgumentKind(BaseEnumeration): @@ -1162,12 +1168,36 @@ def is_definition(self): """ return conf.lib.clang_isCursorDefinition(self) + def is_const_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared 'const'. + """ + return conf.lib.clang_CXXMethod_isConst(self) + + def is_mutable_field(self): + """Returns True if the cursor refers to a C++ field that is declared + 'mutable'. + """ + return conf.lib.clang_CXXField_isMutable(self) + + def is_pure_virtual_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared pure virtual. + """ + return conf.lib.clang_CXXMethod_isPureVirtual(self) + def is_static_method(self): """Returns True if the cursor refers to a C++ member function or member function template that is declared 'static'. """ return conf.lib.clang_CXXMethod_isStatic(self) + def is_virtual_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared 'virtual'. + """ + return conf.lib.clang_CXXMethod_isVirtual(self) + def get_definition(self): """ If the cursor is a reference to a declaration or a declaration of @@ -1673,6 +1703,7 @@ def __repr__(self): TypeKind.VARIABLEARRAY = TypeKind(115) TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116) TypeKind.MEMBERPOINTER = TypeKind(117) +TypeKind.AUTO = TypeKind(118) class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" @@ -2877,6 +2908,14 @@ def cursor(self): [Index, c_char_p], c_object_p), + ("clang_CXXField_isMutable", + [Cursor], + bool), + + ("clang_CXXMethod_isConst", + [Cursor], + bool), + ("clang_CXXMethod_isPureVirtual", [Cursor], bool), diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index a5224aafabc1..c5ea50516ad2 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -97,6 +97,36 @@ def test_canonical(): assert len(cursors) == 3 assert cursors[1].canonical == cursors[2].canonical +def test_is_const_method(): + """Ensure Cursor.is_const_method works.""" + source = 'class X { void foo() const; void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + assert cls is not None + assert foo is not None + assert bar is not None + + assert foo.is_const_method() + assert not bar.is_const_method() + +def test_is_mutable_field(): + """Ensure Cursor.is_mutable_field works.""" + source = 'class X { int x_; mutable int y_; };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + x_ = get_cursor(tu, 'x_') + y_ = get_cursor(tu, 'y_') + assert cls is not None + assert x_ is not None + assert y_ is not None + + assert not x_.is_mutable_field() + assert y_.is_mutable_field() + def test_is_static_method(): """Ensure Cursor.is_static_method works.""" @@ -113,6 +143,36 @@ def test_is_static_method(): assert foo.is_static_method() assert not bar.is_static_method() +def test_is_pure_virtual_method(): + """Ensure Cursor.is_pure_virtual_method works.""" + source = 'class X { virtual void foo() = 0; virtual void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + assert cls is not None + assert foo is not None + assert bar is not None + + assert foo.is_pure_virtual_method() + assert not bar.is_pure_virtual_method() + +def test_is_virtual_method(): + """Ensure Cursor.is_virtual_method works.""" + source = 'class X { virtual void foo(); void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + assert cls is not None + assert foo is not None + assert bar is not None + + assert foo.is_virtual_method() + assert not bar.is_virtual_method() + def test_underlying_type(): tu = get_tu('typedef int foo;') typedef = get_cursor(tu, 'foo') diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py index 8cabc512d4c5..5bac289625be 100644 --- a/bindings/python/tests/cindex/test_cursor_kind.py +++ b/bindings/python/tests/cindex/test_cursor_kind.py @@ -13,6 +13,7 @@ def test_get_all_kinds(): assert CursorKind.OBJ_SELF_EXPR in kinds assert CursorKind.MS_ASM_STMT in kinds assert CursorKind.MODULE_IMPORT_DECL in kinds + assert CursorKind.TYPE_ALIAS_TEMPLATE_DECL in kinds def test_kind_groups(): """Check that every kind classifies to exactly one group.""" diff --git a/bindings/python/tests/cindex/test_type.py b/bindings/python/tests/cindex/test_type.py index f3dadf999bd8..f2184338be4b 100644 --- a/bindings/python/tests/cindex/test_type.py +++ b/bindings/python/tests/cindex/test_type.py @@ -134,7 +134,7 @@ def test_equal(): def test_type_spelling(): """Ensure Type.spelling works.""" - tu = get_tu('int c[5]; int i[]; int x; int v[x];') + tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];') c = get_cursor(tu, 'c') i = get_cursor(tu, 'i') x = get_cursor(tu, 'x') @@ -253,7 +253,7 @@ def test_function_variadic(): def test_element_type(): """Ensure Type.element_type works.""" - tu = get_tu('int c[5]; int i[]; int x; int v[x];') + tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];') c = get_cursor(tu, 'c') i = get_cursor(tu, 'i') v = get_cursor(tu, 'v') diff --git a/cmake/caches/Apple-stage1.cmake b/cmake/caches/Apple-stage1.cmake new file mode 100644 index 000000000000..a5c3fdbbdfd0 --- /dev/null +++ b/cmake/caches/Apple-stage1.cmake @@ -0,0 +1,32 @@ +# This file sets up a CMakeCache for Apple-style bootstrap builds. It can be +# used on any Darwin system to approximate Apple Clang builds. + +if($ENV{DT_TOOLCHAIN_DIR}) + set(CMAKE_INSTALL_PREFIX $ENV{DT_TOOLCHAIN_DIR}/usr/) +else() + set(CMAKE_INSTALL_PREFIX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.toolchain/usr/) +endif() + +set(LLVM_TARGETS_TO_BUILD X86 CACHE STRING "") +set(CLANG_VENDOR Apple CACHE STRING "") +set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "") +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(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 "") + +#bootstrap +set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") +set(CLANG_BOOTSTRAP_CMAKE_ARGS + -C ${CMAKE_CURRENT_LIST_DIR}/Apple-stage2.cmake + CACHE STRING "") diff --git a/cmake/caches/Apple-stage2.cmake b/cmake/caches/Apple-stage2.cmake new file mode 100644 index 000000000000..bb319aaeb86c --- /dev/null +++ b/cmake/caches/Apple-stage2.cmake @@ -0,0 +1,30 @@ +# This file sets up a CMakeCache for Apple-style stage2 bootstrap. It is +# 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(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(CLANG_LINKS_TO_CREATE clang++ cc c++ 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(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 "") + +# setup toolchain +set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "") +set(LLVM_TOOLCHAIN_TOOLS + llvm-dsymutil + llvm-cov + llvm-dwarfdump + llvm-profdata + CACHE STRING "") diff --git a/cmake/caches/README.txt b/cmake/caches/README.txt new file mode 100644 index 000000000000..55e5e159db13 --- /dev/null +++ b/cmake/caches/README.txt @@ -0,0 +1,18 @@ +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: + +cmake -G + -C /tools/clang/cmake/caches/Apple-stage1.cmake + -DCMAKE_BUILD_TYPE=Release + [-DCMAKE_INSTALL_PREFIX=] + + +Building the `bootstrap` target from this generation will build clang, and +`bootstrap-install` will install it. diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst index 66ed3447fdb1..93f63143210b 100644 --- a/docs/AddressSanitizer.rst +++ b/docs/AddressSanitizer.rst @@ -196,12 +196,11 @@ Disabling Instrumentation with ``__attribute__((no_sanitize("address")))`` -------------------------------------------------------------------------- Some code should not be instrumented by AddressSanitizer. One may use the -function attribute ``__attribute__((no_sanitize("address")))`` -(which has deprecated synonyms -:ref:`no_sanitize_address ` and -`no_address_safety_analysis`) to disable instrumentation of a particular -function. This attribute may not be supported by other compilers, so we suggest -to use it together with ``__has_feature(address_sanitizer)``. +function attribute ``__attribute__((no_sanitize("address")))`` (which has +deprecated synonyms `no_sanitize_address` and `no_address_safety_analysis`) to +disable instrumentation of a particular function. This attribute may not be +supported by other compilers, so we suggest to use it together with +``__has_feature(address_sanitizer)``. Suppressing Errors in Recompiled Code (Blacklist) ------------------------------------------------- @@ -268,5 +267,4 @@ check-asan`` command. More Information ================ -`http://code.google.com/p/address-sanitizer `_ - +``_ diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst index e282824952ba..a763ddeaeb10 100644 --- a/docs/AttributeReference.rst +++ b/docs/AttributeReference.rst @@ -1,1760 +1,13 @@ .. ------------------------------------------------------------------- NOTE: This file is automatically generated by running clang-tblgen - -gen-attr-docs. Do not edit this file by hand!! + -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. ------------------------------------------------------------------- =================== Attributes in Clang -=================== -.. contents:: - :local: - -Introduction -============ - -This page lists the attributes currently supported by Clang. - -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. - - -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. - - -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. - - -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(macosx,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. - -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. - -``macosx`` - Apple's Mac OS X operating system. The minimum deployment target is - specified by the ``-mmacosx-version-min=*version*`` command-line argument. - -A declaration can 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. - -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(macosx,introduced=10.4))); - void g(void) __attribute__((availability(macosx,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 macosx and ios availability from above. - void g(void) __attribute__((availability(macosx,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(macosx,introduced=10.4))); - - (id)method2 __attribute__((availability(macosx,introduced=10.4))); - @end - - @interface B : A - - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later - - (id)method __attribute__((availability(macosx,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. - - -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)``. - - -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. - - -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. - - -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 - - -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. - - -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). - - -Variable Attributes -=================== - - -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 - - -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. - - -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. - - -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. - - -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. - - -__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. - - -Statement Attributes -==================== - - -fallthrough (clang::fallthrough) --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","X","","", "" - -The ``clang::fallthrough`` attribute is used along with the -``-Wimplicit-fallthrough`` argument 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. - -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: - -.. 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. - - -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". - - -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 -------- -.. 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 ---------------- -.. 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. - - +=================== \ No newline at end of file diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst index 45ea32717995..b4968ef1036f 100644 --- a/docs/ClangFormat.rst +++ b/docs/ClangFormat.rst @@ -16,7 +16,7 @@ to format C/C++/Obj-C code. .. code-block:: console $ clang-format -help - OVERVIEW: A tool to format C/C++/Obj-C code. + OVERVIEW: A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code. If no arguments are specified, it formats the code from standard input and writes the result to the standard output. @@ -30,44 +30,53 @@ to format C/C++/Obj-C code. Clang-format options: - -cursor= - The position of the cursor when invoking - clang-format from an editor integration - -dump-config - Dump configuration options to stdout and exit. - Can be used with -style option. - -i - Inplace edit s, if specified. - -length= - Format a range of this length (in bytes). - Multiple ranges can be formatted by specifying - several -offset and -length pairs. - When only a single -offset is specified without - -length, clang-format will format up to the end - of the file. - Can only be used with one input file. - -lines= - : - format a range of - lines (both 1-based). - Multiple ranges can be formatted by specifying - several -lines arguments. - Can't be used with -offset and -length. - Can only be used with one input file. - -offset= - Format a range starting at this byte offset. - Multiple ranges can be formatted by specifying - several -offset and -length pairs. - Can only be used with one input file. - -output-replacements-xml - Output replacements as XML. - -style= - Coding style, currently supports: - LLVM, Google, Chromium, Mozilla, WebKit. - Use -style=file to load style configuration from - .clang-format file located in one of the parent - directories of the source file (or current - directory for stdin). - Use -style="{key: value, ...}" to set specific - parameters, e.g.: - -style="{BasedOnStyle: llvm, IndentWidth: 8}" + -assume-filename= - When reading from stdin, clang-format assumes this + filename to look for a style config file (with + -style=file) and to determine the language. + -cursor= - The position of the cursor when invoking + clang-format from an editor integration + -dump-config - Dump configuration options to stdout and exit. + Can be used with -style option. + -fallback-style= - The name of the predefined style used as a + fallback in case clang-format is invoked with + -style=file, but can not find the .clang-format + file to use. + Use -fallback-style=none to skip formatting. + -i - Inplace edit s, if specified. + -length= - Format a range of this length (in bytes). + Multiple ranges can be formatted by specifying + several -offset and -length pairs. + When only a single -offset is specified without + -length, clang-format will format up to the end + of the file. + Can only be used with one input file. + -lines= - : - format a range of + lines (both 1-based). + Multiple ranges can be formatted by specifying + several -lines arguments. + Can't be used with -offset and -length. + Can only be used with one input file. + -offset= - Format a range starting at this byte offset. + Multiple ranges can be formatted by specifying + several -offset and -length pairs. + Can only be used with one input file. + -output-replacements-xml - Output replacements as XML. + -sort-includes - Sort touched include lines + -style= - Coding style, currently supports: + LLVM, Google, Chromium, Mozilla, WebKit. + Use -style=file to load style configuration from + .clang-format file located in one of the parent + directories of the source file (or current + directory for stdin). + Use -style="{key: value, ...}" to set specific + parameters, e.g.: + -style="{BasedOnStyle: llvm, IndentWidth: 8}" - General options: + Generic Options: - -help - Display available options (-help-hidden for more) - -help-list - Display list of available options (-help-list-hidden for more) - -version - Display the version of this program + -help - Display available options (-help-hidden for more) + -help-list - Display list of available options (-help-list-hidden for more) + -version - Display the version of this program When the desired code formatting style is different from the available options, diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 031daeeaa123..bfabd5985ca0 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -150,26 +150,61 @@ the configuration (without a prefix: ``Auto``). **AccessModifierOffset** (``int``) The extra indent or outdent of access modifiers, e.g. ``public:``. -**AlignAfterOpenBracket** (``bool``) +**AlignAfterOpenBracket** (``BracketAlignmentStyle``) 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 - \code - someLongFunction(argument1, - argument2); - \endcode + + Possible values: + + * ``BAS_Align`` (in configuration: ``Align``) + Align parameters on the open bracket, e.g.: + + .. code-block:: c++ + + someLongFunction(argument1, + argument2); + * ``BAS_DontAlign`` (in configuration: ``DontAlign``) + Don't align, instead use ``ContinuationIndentWidth``, e.g.: + + .. code-block:: c++ + + 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.: + + .. code-block:: c++ + + someLongFunction( + argument1, argument2); + **AlignConsecutiveAssignments** (``bool``) If ``true``, aligns consecutive assignments. This will align the assignment operators of consecutive lines. This will result in formattings like - \code - int aaaa = 12; - int b = 23; - int ccc = 23; - \endcode + + .. code-block:: c++ + + int aaaa = 12; + int b = 23; + int ccc = 23; + +**AlignConsecutiveDeclarations** (``bool``) + If ``true``, aligns consecutive declarations. + + This will align the declaration names of consecutive lines. This + will result in formattings like + + .. code-block:: c++ + + int aaaa = 12; + float b = 23; + std::string ccc = 23; **AlignEscapedNewlinesLeft** (``bool``) If ``true``, aligns escaped newlines as far left as possible. @@ -219,7 +254,8 @@ the configuration (without a prefix: ``Auto``). single line. **AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``) - The function definition return type breaking style to use. + The function definition return type breaking style to use. This + option is deprecated and is retained for backwards compatibility. Possible values: @@ -229,7 +265,25 @@ the configuration (without a prefix: ``Auto``). * ``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. + Always break after the return types of top-level functions. + + +**AlwaysBreakAfterReturnType** (``ReturnTypeBreakingStyle``) + The function declaration return type breaking style to use. + + Possible values: + + * ``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``) @@ -252,6 +306,30 @@ the configuration (without a prefix: ``Auto``). If ``false``, a function declaration's or function definition's parameters will either all be on the same line or will have one line each. +**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. + + Nested configuration flags: + + * ``bool AfterClass`` Wrap class definitions. + * ``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 AfterStruct`` Wrap struct definitions. + * ``bool AfterUnion`` Wrap union definitions. + * ``bool BeforeCatch`` Wrap before ``catch``. + * ``bool BeforeElse`` Wrap before ``else``. + * ``bool IndentBraces`` Indent the wrapped braces themselves. + + +**BreakAfterJavaFieldAnnotations** (``bool``) + Break after each annotation on a field in Java files. + **BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) The way to wrap binary operators. @@ -279,13 +357,17 @@ the configuration (without a prefix: ``Auto``). Like ``Attach``, but break before braces on enum, function, and record definitions. * ``BS_Stroustrup`` (in configuration: ``Stroustrup``) - Like ``Attach``, but break before function definitions, 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``. **BreakBeforeTernaryOperators** (``bool``) @@ -356,13 +438,47 @@ the configuration (without a prefix: ``Auto``). instead of as function calls. These are expected to be macros of the form: - \code - FOREACH(, ...) - - \endcode + + .. code-block:: c++ + + FOREACH(, ...) + + + In the .clang-format configuration file, this can be configured like: + + .. code-block:: c++ + + ForEachMacros: ['RANGES_FOR', 'FOREACH'] For example: BOOST_FOREACH. +**IncludeCategories** (``std::vector``) + 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 + 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). + + To configure this in the .clang-format file, use: + + .. code-block:: c++ + + IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: '.\*' + Priority: 1 + **IndentCaseLabels** (``bool``) Indent case labels one level from the switch statement. @@ -546,6 +662,26 @@ the configuration (without a prefix: ``Auto``). .. 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 +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 +decision on options they don't really care about. + +The goal of the clang-format project is more on the side of supporting a +limited set of styles really well as opposed to supporting every single style +used by a codebase somewhere in the wild. Of course, we do want to support all +major projects and thus have established the following bar for adding style +options. Each new style option must .. + + * be used in a project of significant size (have dozens of contributors) + * have a publicly accessible style guide + * have a person willing to contribute and maintain patches + Examples ======== diff --git a/docs/ClangTools.rst b/docs/ClangTools.rst index 8957541c2504..e371596b240c 100644 --- a/docs/ClangTools.rst +++ b/docs/ClangTools.rst @@ -82,7 +82,7 @@ fixit-hints offered by clang. See :doc:`HowToSetupToolingForLLVM` for instructions on how to setup and used `clang-check`. ``clang-format`` -~~~~~~~~~~~~~~~~ +---------------- Clang-format is both a :doc:`library ` and a :doc:`stand-alone tool ` with the goal of automatically reformatting C++ sources files @@ -93,18 +93,6 @@ as a user tool (ideally with powerful IDE integrations) and as part of other refactoring tools, e.g. to do a reformatting of all the lines changed during a renaming. -``clang-modernize`` -~~~~~~~~~~~~~~~~~~~ -``clang-modernize`` migrates C++ code to use C++11 features where appropriate. -Currently it can: - -* convert loops to range-based for loops; - -* convert null pointer constants (like ``NULL`` or ``0``) to C++11 ``nullptr``; - -* replace the type specifier in variable declarations with the ``auto`` type specifier; - -* add the ``override`` specifier to applicable member functions. Extra Clang Tools ================= @@ -114,6 +102,15 @@ they'll be tracked here. The focus of this documentation is on the scope and features of the tools for other tool developers; each tool should provide its own user-focused documentation. +``clang-tidy`` +-------------- + +`clang-tidy `_ is a clang-based C++ +linter tool. It provides an extensible framework for building compiler-based +static analyses detecting and fixing bug-prone patterns, performance, +portability and maintainability issues. + + Ideas for new Tools =================== @@ -124,27 +121,6 @@ Ideas for new Tools ``foo.begin()`` into ``begin(foo)`` and similarly for ``end()``, where ``foo`` is a standard container. We could also detect similar patterns for arrays. -* ``make_shared`` / ``make_unique`` conversion. Part of this transformation - can be incorporated into the ``auto`` transformation. Will convert - - .. code-block:: c++ - - std::shared_ptr sp(new Foo); - std::unique_ptr up(new Foo); - - func(std::shared_ptr(new Foo), bar()); - - into: - - .. code-block:: c++ - - auto sp = std::make_shared(); - auto up = std::make_unique(); // In C++14 mode. - - // This also affects correctness. For the cases where bar() throws, - // make_shared() is safe and the original code may leak. - func(std::make_shared(), bar()); - * ``tr1`` removal tool. Will migrate source code from using TR1 library features to C++11 library. For example: diff --git a/docs/CommandGuide/clang.rst b/docs/CommandGuide/clang.rst index 39dbe02a0b43..2b4569592a9a 100644 --- a/docs/CommandGuide/clang.rst +++ b/docs/CommandGuide/clang.rst @@ -257,6 +257,18 @@ Code Generation Options Generate debug information. Note that Clang debug information works best at -O0. +.. 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 implies :option:`-fmodule-format=obj`. + + 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 diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst index ce1c37bcd408..780ff882d0e3 100644 --- a/docs/ControlFlowIntegrity.rst +++ b/docs/ControlFlowIntegrity.rst @@ -20,20 +20,72 @@ program's control flow. These schemes have been optimized for performance, allowing developers to enable them in release builds. To enable Clang's available CFI schemes, use the flag ``-fsanitize=cfi``. -As currently implemented, CFI relies 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 enabled, and are statically linked into the program. This may -preclude the use of shared libraries in some cases. +You can also enable a subset of available :ref:`schemes `. +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`_. -Clang currently implements forward-edge CFI for member function calls and -bad cast checking. More schemes are under development. +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. .. _gold plugin: http://llvm.org/docs/GoldPlugin.html +.. _cfi-schemes: + +Available schemes +================= + +Available schemes are: + + - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks + `. + - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong + dynamic type. + - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another + unrelated type to the wrong dynamic type. + - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of + the wrong dynamic type. + - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the + wrong dynamic type. + - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic + type. + +You can use ``-fsanitize=cfi`` to enable all the schemes and use +``-fno-sanitize`` flag to narrow down the set of schemes as desired. +For example, you can build your program with +``-fsanitize=cfi -fno-sanitize=cfi-nvcall,cfi-icall`` +to use all schemes except for non-virtual member function call and indirect call +checking. + +Remember that you have to provide ``-flto`` if at least one CFI scheme is +enabled. + +Trapping and Diagnostics +======================== + +By default, CFI will abort the program immediately upon detecting a control +flow integrity violation. You can use the :ref:`-fno-sanitize-trap= +` flag to cause CFI to print a diagnostic +similar to the one below before the program aborts. + +.. code-block:: console + + bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast (vtable address 0x000000425a50) + 0x000000425a50: note: vtable is of type 'A' + 00 00 00 00 f0 f1 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 5a 42 00 + ^ + +If diagnostics are enabled, you can also configure CFI to continue program +execution instead of aborting by using the :ref:`-fsanitize-recover= +` flag. + Forward-Edge CFI for Virtual Calls ----------------------------------- +================================== This scheme checks that virtual calls take place using a vptr of the correct dynamic type; that is, the dynamic type of the called object must be a @@ -41,14 +93,12 @@ derived class of the static type of the object used to make the call. This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``. For this scheme to work, all translation units containing the definition -of a virtual member function (whether inline or not) must be compiled -with ``-fsanitize=cfi-vcall`` enabled and be statically linked into the -program. Classes in the C++ standard library (under namespace ``std``) are -exempted from checking, and therefore programs may be linked against a -pre-built standard library, but this may change in the future. +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted ` types, must be compiled with +``-fsanitize=cfi-vcall`` enabled and be statically linked into the program. Performance -~~~~~~~~~~~ +----------- A performance overhead of less than 1% has been measured by running the Dromaeo benchmark suite against an instrumented version of the Chromium @@ -59,7 +109,7 @@ Note that this scheme has not yet been optimized for binary size; an increase of up to 15% has been observed for Chromium. Bad Cast Checking ------------------ +================= This scheme checks that pointer casts are made to an object of the correct dynamic type; that is, the dynamic type of the object must be a derived class @@ -85,18 +135,16 @@ 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 for a function to perform a forbidden cast to conform with an external API (e.g. the ``allocate`` member function of a standard library allocator). Such -functions may be blacklisted using a :doc:`SanitizerSpecialCaseList`. +functions may be :ref:`blacklisted `. For this scheme to work, all translation units containing the definition -of a virtual member function (whether inline or not) must be compiled with +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted ` types, must be compiled with ``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled -and be statically linked into the program. Classes in the C++ standard library -(under namespace ``std``) are exempted from checking, and therefore programs -may be linked against a pre-built standard library, but this may change in -the future. +and be statically linked into the program. Non-Virtual Member Function Call Checking ------------------------------------------ +========================================= This scheme checks that non-virtual calls take place using an object of the correct dynamic type; that is, the dynamic type of the called object @@ -106,16 +154,14 @@ polymorphic class type. This CFI scheme can be enabled on its own using ``-fsanitize=cfi-nvcall``. For this scheme to work, all translation units containing the definition -of a virtual member function (whether inline or not) must be compiled -with ``-fsanitize=cfi-nvcall`` enabled and be statically linked into the -program. Classes in the C++ standard library (under namespace ``std``) are -exempted from checking, and therefore programs may be linked against a -pre-built standard library, but this may change in the future. +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted ` types, must be compiled with +``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program. .. _cfi-strictness: Strictness -~~~~~~~~~~ +---------- If a class has a single non-virtual base and does not introduce or override virtual member functions or fields other than an implicitly defined virtual @@ -129,13 +175,97 @@ member functions on class instances with specific properties that works under most compilers and should not have security implications, so we allow it by default. It can be disabled with ``-fsanitize=cfi-cast-strict``. +Indirect Function Call Checking +=============================== + +This scheme checks that function calls take place using a function of the +correct dynamic type; that is, the dynamic type of the function must match +the static type used at the call. This CFI scheme can be enabled on its own +using ``-fsanitize=cfi-icall``. + +For this scheme to work, each indirect function call in the program, other +than calls in :ref:`blacklisted ` functions, must call a +function which was either compiled with ``-fsanitize=cfi-icall`` enabled, +or whose address was taken by a function in a translation unit compiled with +``-fsanitize=cfi-icall``. + +If a function in a translation unit compiled with ``-fsanitize=cfi-icall`` +takes the address of a function not compiled with ``-fsanitize=cfi-icall``, +that address may differ from the address taken by a function in a translation +unit not compiled with ``-fsanitize=cfi-icall``. This is technically a +violation of the C and C++ standards, but it should not affect most programs. + +Each translation unit compiled with ``-fsanitize=cfi-icall`` must be +statically linked into the program or shared library, and calls across +shared library boundaries are handled as if the callee was not compiled with +``-fsanitize=cfi-icall``. + +This scheme is currently only supported on the x86 and x86_64 architectures. + +``-fsanitize=cfi-icall`` and ``-fsanitize=function`` +---------------------------------------------------- + +This tool is similar to ``-fsanitize=function`` in that both tools check +the types of function calls. However, the two tools occupy different points +on the design space; ``-fsanitize=function`` is a developer tool designed +to find bugs in local development builds, whereas ``-fsanitize=cfi-icall`` +is a security hardening mechanism designed to be deployed in release builds. + +``-fsanitize=function`` has a higher space and time overhead due to a more +complex type check at indirect call sites, as well as a need for run-time +type information (RTTI), which may make it unsuitable for deployment. Because +of the need for RTTI, ``-fsanitize=function`` can only be used with C++ +programs, whereas ``-fsanitize=cfi-icall`` can protect both C and C++ programs. + +On the other hand, ``-fsanitize=function`` conforms more closely with the C++ +standard and user expectations around interaction with shared libraries; +the identity of function pointers is maintained, and calls across shared +library boundaries are no different from calls within a single program or +shared library. + +.. _cfi-blacklist: + +Blacklist +========= + +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. + src:bad_file.cpp + src:bad_header.h + # Ignore all functions with names containing MyFooBar. + fun:*MyFooBar* + # Ignore all types in the standard library. + type:std::* + # Ignore all types with a uuid attribute. + type:attr:uuid + +.. _cfi-cross-dso: + +Shared library support +====================== + +Use **-f[no-]sanitize-cfi-cross-dso** to enable the cross-DSO control +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``. + Design ------- +====== Please refer to the :doc:`design document`. Publications ------------- +============ `Control-Flow Integrity: Principles, Implementations, and Applications `_. Martin Abadi, Mihai Budiu, Úlfar Erlingsson, Jay Ligatti. diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst index 89aa038d003e..b4aacd365670 100644 --- a/docs/ControlFlowIntegrityDesign.rst +++ b/docs/ControlFlowIntegrityDesign.rst @@ -273,3 +273,227 @@ Eliminating Bit Vector Checks for All-Ones Bit Vectors If the bit vector is all ones, the bit vector check is redundant; we simply need to check that the address is in range and well aligned. This is more likely to occur if the virtual tables are padded. + +Forward-Edge CFI for Indirect Function Calls +============================================ + +Under forward-edge CFI for indirect function calls, each unique function +type has its own bit vector, and at each call site we need to check that the +function pointer is a member of the function type's bit vector. This scheme +works in a similar way to forward-edge CFI for virtual calls, the distinction +being that we need to build bit vectors of function entry points rather than +of virtual tables. + +Unlike when re-arranging global variables, we cannot re-arrange functions +in a particular order and base our calculations on the layout of the +functions' entry points, as we have no idea how large a particular function +will end up being (the function sizes could even depend on how we arrange +the functions). Instead, we build a jump table, which is a block of code +consisting of one branch instruction for each of the functions in the bit +set that branches to the target function, and redirect any taken function +addresses to the corresponding jump table entry. In this way, the distance +between function entry points is predictable and controllable. In the object +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 +addresses: + +.. code-block:: none + + f: + mov 0, %eax + ret + + g: + mov 1, %eax + ret + + h: + mov 2, %eax + ret + + foo: + mov f, %eax + mov g, %edx + mov h, %ecx + ret + +Our jump table will (conceptually) look like this: + +.. code-block:: none + + f: + jmp .Ltmp0 ; 5 bytes + int3 ; 1 byte + int3 ; 1 byte + int3 ; 1 byte + + g: + jmp .Ltmp1 ; 5 bytes + int3 ; 1 byte + int3 ; 1 byte + int3 ; 1 byte + + h: + jmp .Ltmp2 ; 5 bytes + int3 ; 1 byte + int3 ; 1 byte + int3 ; 1 byte + + .Ltmp0: + mov 0, %eax + ret + + .Ltmp1: + mov 1, %eax + ret + + .Ltmp2: + mov 2, %eax + ret + + foo: + mov f, %eax + mov g, %edx + mov h, %ecx + ret + +Because the addresses of ``f``, ``g``, ``h`` are evenly spaced at a power of +2, and function types do not overlap (unlike class types with base classes), +we can normally apply the `Alignment`_ and `Eliminating Bit Vector Checks +for All-Ones Bit Vectors`_ optimizations thus simplifying the check at each +call site to a range and alignment check. + +Shared library support +====================== + +**EXPERIMENTAL** + +The basic CFI mode described above assumes that the application is a +monolithic binary; at least that all possible virtual/indirect call +targets and the entire class hierarchy are known at link time. The +cross-DSO mode, enabled with **-f[no-]sanitize-cfi-cross-dso** relaxes +this requirement by allowing virtual and indirect calls to cross the +DSO boundary. + +Assuming the following setup: the binary consists of several +instrumented and several uninstrumented DSOs. Some of them may be +dlopen-ed/dlclose-d periodically, even frequently. + + - Calls made from uninstrumented DSOs are not checked and just work. + - Calls inside any instrumented DSO are fully protected. + - Calls between different instrumented DSOs are also protected, with + a performance penalty (in addition to the monolithic CFI + overhead). + - Calls from an instrumented DSO to an uninstrumented one are + unchecked and just work, with performance penalty. + - Calls from an instrumented DSO outside of any known DSO are + detected as CFI violations. + +In the monolithic scheme a call site is instrumented as + +.. code-block:: none + + if (!InlinedFastCheck(f)) + abort(); + call *f + +In the cross-DSO scheme it becomes + +.. code-block:: none + + if (!InlinedFastCheck(f)) + __cfi_slowpath(CallSiteTypeId, f); + call *f + +CallSiteTypeId +-------------- + +``CallSiteTypeId`` is a stable process-wide identifier of the +call-site type. For a virtual call site, the type in question is the class +type; for an indirect function call it is the function signature. The +mapping from a type to an identifier is an ABI detail. In the current, +experimental, implementation the identifier of type T is calculated as +follows: + + - Obtain the mangled name for "typeinfo name for T". + - Calculate MD5 hash of the name as a string. + - Reinterpret the first 8 bytes of the hash as a little-endian + 64-bit integer. + +It is possible, but unlikely, that collisions in the +``CallSiteTypeId`` hashing will result in weaker CFI checks that would +still be conservatively correct. + +CFI_Check +--------- + +In the general case, only the target DSO knows whether the call to +function ``f`` with type ``CallSiteTypeId`` is valid or not. To +export this information, every DSO implements + +.. code-block:: none + + 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. + +The basic implementation is a large switch statement over all values +of CallSiteTypeId supported by this DSO, and each case is similar to +the InlinedFastCheck() in the basic CFI mode. + +CFI Shadow +---------- + +To route CFI checks to the target DSO's __cfi_check function, a +mapping from possible virtual / indirect call targets to +the corresponding __cfi_check functions is maintained. This mapping is +implemented as a sparse array of 2 bytes for every possible page (4096 +bytes) of memory. The table is kept readonly (FIXME: not yet) most of +the time. + +There are 3 types of shadow values: + + - Address in a CFI-instrumented DSO. + - Unchecked address (a “trusted” non-instrumented DSO). Encoded as + value 0xFFFF. + - Invalid address (everything else). Encoded as value 0. + +For a CFI-instrumented DSO, a shadow value encodes the address of the +__cfi_check function for all call targets in the corresponding memory +page. If Addr is the target address, and V is the shadow value, then +the address of __cfi_check is calculated as + +.. code-block:: none + + __cfi_check = AlignUpTo(Addr, 4096) - (V + 1) * 4096 + +This works as long as __cfi_check is aligned by 4096 bytes and located +below any call targets in its DSO, but not more than 256MB apart from +them. + +CFI_SlowPath +------------ + +The slow path check is implemented in compiler-rt library as + +.. code-block:: none + + void __cfi_slowpath(uint64 CallSiteTypeId, void *TargetAddr) + +This functions loads a shadow value for ``TargetAddr``, finds the +address of __cfi_check as described above and calls that. + +Position-independent executable requirement +------------------------------------------- + +Cross-DSO CFI mode requires that the main executable is built as PIE. +In non-PIE executables the address of an external function (taken from +the main executable) is the address of that function’s PLT record in +the main executable. This would break the CFI checks. diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst index 7959179d4916..c4af5b112ac7 100644 --- a/docs/InternalsManual.rst +++ b/docs/InternalsManual.rst @@ -1995,7 +1995,7 @@ are similar. * Make sure that ``children()`` visits all of the subexpressions. This is important for a number of features (e.g., IDE support, C++ variadic templates). If you have sub-types, you'll also need to visit those - sub-types in ``RecursiveASTVisitor`` and ``DataRecursiveASTVisitor``. + sub-types in ``RecursiveASTVisitor``. * Add printing support (``StmtPrinter.cpp``) for your expression. * Add profiling support (``StmtProfile.cpp``) for your AST node, noting the distinguishing (non-source location) characteristics of an instance of diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 6a4dd5ccbf3c..333dee618ce7 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -415,7 +415,7 @@ dash indicates that an operation is not accepted according to a corresponding specification. ============================== ======= ======= ======= ======= - Opeator OpenCL AltiVec GCC NEON + Operator OpenCL AltiVec GCC NEON ============================== ======= ======= ======= ======= [] yes yes yes -- unary operators +, -- yes yes yes -- @@ -1017,8 +1017,8 @@ The following type trait primitives are supported by Clang: ``argtypes...`` such that no non-trivial functions are called as part of that initialization. This trait is required to implement the C++11 standard library. -* ``__is_destructible`` (MSVC 2013): partially implemented -* ``__is_nothrow_destructible`` (MSVC 2013): partially implemented +* ``__is_destructible`` (MSVC 2013) +* ``__is_nothrow_destructible`` (MSVC 2013) * ``__is_nothrow_assignable`` (MSVC 2013, clang) * ``__is_constructible`` (MSVC 2013, clang) * ``__is_nothrow_constructible`` (MSVC 2013, clang) @@ -1540,6 +1540,33 @@ takes no arguments and produces a void result. Query for this feature with ``__has_builtin(__builtin_unreachable)``. +``__builtin_unpredictable`` +--------------------------- + +``__builtin_unpredictable`` is used to indicate that a branch condition is +unpredictable by hardware mechanisms such as branch prediction logic. + +**Syntax**: + +.. code-block:: c++ + + __builtin_unpredictable(long long) + +**Example of use**: + +.. code-block:: c++ + + if (__builtin_unpredictable(x > 0)) { + foo(); + } + +**Description**: + +The ``__builtin_unpredictable()`` builtin is expected to be used with control +flow conditions such as in ``if`` and ``switch`` statements. + +Query for this feature with ``__has_builtin(__builtin_unpredictable)``. + ``__sync_swap`` --------------- @@ -1652,17 +1679,20 @@ an example of their usage: errorcode_t security_critical_application(...) { unsigned x, y, result; ... - if (__builtin_umul_overflow(x, y, &result)) + if (__builtin_mul_overflow(x, y, &result)) return kErrorCodeHackers; ... use_multiply(result); ... } -A complete enumeration of the builtins are: +Clang provides the following checked arithmetic builtins: .. code-block:: c + bool __builtin_add_overflow (type1 x, type2 y, type3 *sum); + bool __builtin_sub_overflow (type1 x, type2 y, type3 *diff); + bool __builtin_mul_overflow (type1 x, type2 y, type3 *prod); bool __builtin_uadd_overflow (unsigned x, unsigned y, unsigned *sum); bool __builtin_uaddl_overflow (unsigned long x, unsigned long y, unsigned long *sum); bool __builtin_uaddll_overflow(unsigned long long x, unsigned long long y, unsigned long long *sum); @@ -1682,6 +1712,21 @@ A complete enumeration of the builtins are: bool __builtin_smull_overflow (long x, long y, long *prod); bool __builtin_smulll_overflow(long long x, long long y, long long *prod); +Each builtin performs the specified mathematical operation on the +first two arguments and stores the result in the third argument. If +possible, the result will be equal to mathematically-correct result +and the builtin will return 0. Otherwise, the builtin will return +1 and the result will be equal to the unique value that is equivalent +to the mathematically-correct result modulo two raised to the *k* +power, where *k* is the number of bits in the result type. The +behavior of these builtins is well-defined for all argument values. + +The first three builtins work generically for operands of any integer type, +including boolean types. The operands need not have the same type as each +other, or as the result. The other builtins may implicitly promote or +convert their operands before performing the operation. + +Query for this feature with ``__has_builtin(__builtin_add_overflow)``, etc. .. _langext-__c11_atomic: @@ -1715,6 +1760,9 @@ The macros ``__ATOMIC_RELAXED``, ``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, provided, with values corresponding to the enumerators of C11's ``memory_order`` enumeration. +(Note that Clang additionally provides GCC-compatible ``__atomic_*`` +builtins) + Low-level ARM exclusive memory builtins --------------------------------------- @@ -1730,6 +1778,7 @@ instructions for implementing atomic operations. void __builtin_arm_clrex(void); The types ``T`` currently supported are: + * Integer types with width at most 64 bits (or 128 bits on AArch64). * Floating-point types * Pointer types. @@ -1748,6 +1797,26 @@ care should be exercised. For these reasons the higher level atomic primitives should be preferred where possible. +Non-temporal load/store builtins +-------------------------------- + +Clang provides overloaded builtins allowing generation of non-temporal memory +accesses. + +.. code-block:: c + + T __builtin_nontemporal_load(T *addr); + void __builtin_nontemporal_store(T value, T *addr); + +The types ``T`` currently supported are: + +* Integer types. +* Floating-point types. +* Vector types. + +Note that the compiler does not guarantee that non-temporal loads or stores +will be used. + Non-standard C++11 Attributes ============================= @@ -1990,11 +2059,23 @@ iterations. Full unrolling is only possible if the loop trip count is known at compile time. Partial unrolling replicates the loop body within the loop and reduces the trip count. -If ``unroll(full)`` is specified the unroller will attempt to fully unroll the +If ``unroll(enable)`` is specified the unroller will attempt to fully unroll the loop if the trip count is known at compile time. If the fully unrolled code size is greater than an internal limit the loop will be partially unrolled up to this -limit. If the loop count is not known at compile time the loop will not be -unrolled. +limit. If the trip count is not known at compile time the loop will be partially +unrolled with a heuristically chosen unroll factor. + +.. code-block:: c++ + + #pragma clang loop unroll(enable) + for(...) { + ... + } + +If ``unroll(full)`` is specified the unroller will attempt to fully unroll the +loop if the trip count is known at compile time identically to +``unroll(enable)``. However, with ``unroll(full)`` the loop will not be unrolled +if the loop count is not known at compile time. .. code-block:: c++ @@ -2006,7 +2087,7 @@ unrolled. The unroll count can be specified explicitly with ``unroll_count(_value_)`` where _value_ is a positive integer. If this value is greater than the trip count the loop will be fully unrolled. Otherwise the loop is partially unrolled subject -to the same code size limit as with ``unroll(full)``. +to the same code size limit as with ``unroll(enable)``. .. code-block:: c++ diff --git a/docs/LeakSanitizer.rst b/docs/LeakSanitizer.rst index d4b4fa02d730..85918088ccdb 100644 --- a/docs/LeakSanitizer.rst +++ b/docs/LeakSanitizer.rst @@ -28,6 +28,4 @@ There are plans to support LeakSanitizer in :doc:`MemorySanitizer` builds. More Information ================ -`https://code.google.com/p/address-sanitizer/wiki/LeakSanitizer -`_ - +``_ diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index a555bb339fc1..48f061c60c73 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -100,8 +100,8 @@ recordDecl(decl().bind("id"), hasName("::MyClass")) Return typeNameParameters -Matcher<CXXCtorInitializer>ctorInitializerMatcher<CXXCtorInitializer>... -
Matches constructor initializers.
+Matcher<CXXCtorInitializer>cxxCtorInitializerMatcher<CXXCtorInitializer>...
+
Matches constructor initializers.
 
 Examples matches i(42).
   class C {
@@ -144,8 +144,8 @@ classTemplateSpecializationDecl()
 
-Matcher<Decl>constructorDeclMatcher<CXXConstructorDecl>... -
Matches C++ constructor declarations.
+Matcher<Decl>cxxConstructorDeclMatcher<CXXConstructorDecl>...
+
Matches C++ constructor declarations.
 
 Example matches Foo::Foo() and Foo::Foo(int)
   class Foo {
@@ -157,6 +157,42 @@ Example matches Foo::Foo() and Foo::Foo(int)
 
+Matcher<Decl>cxxConversionDeclMatcher<CXXConversionDecl>... +
Matches conversion operator declarations.
+
+Example matches the operator.
+  class X { operator int() const; };
+
+ + +Matcher<Decl>cxxDestructorDeclMatcher<CXXDestructorDecl>... +
Matches explicit C++ destructor declarations.
+
+Example matches Foo::~Foo()
+  class Foo {
+   public:
+    virtual ~Foo();
+  };
+
+ + +Matcher<Decl>cxxMethodDeclMatcher<CXXMethodDecl>... +
Matches method declarations.
+
+Example matches y
+  class X { void y(); };
+
+ + +Matcher<Decl>cxxRecordDeclMatcher<CXXRecordDecl>... +
Matches C++ class declarations.
+
+Example matches X, Z
+  class X;
+  template<class T> class Z {};
+
+ + Matcher<Decl>declMatcher<Decl>...
Matches declarations.
 
@@ -179,17 +215,6 @@ declaratorDecl()
 
-Matcher<Decl>destructorDeclMatcher<CXXDestructorDecl>... -
Matches explicit C++ destructor declarations.
-
-Example matches Foo::~Foo()
-  class Foo {
-   public:
-    virtual ~Foo();
-  };
-
- - Matcher<Decl>enumConstantDeclMatcher<EnumConstantDecl>...
Matches enum constants.
 
@@ -256,14 +281,6 @@ linkageSpecDecl()
 
-Matcher<Decl>methodDeclMatcher<CXXMethodDecl>... -
Matches method declarations.
-
-Example matches y
-  class X { void y(); };
-
- - Matcher<Decl>namedDeclMatcher<NamedDecl>...
Matches a declaration of anything that could have a name.
 
@@ -277,6 +294,17 @@ Example matches X, S, the anonymous union type, i, and U;
 
+Matcher<Decl>namespaceAliasDeclMatcher<NamespaceAliasDecl>... +
Matches a declaration of a namespace alias.
+
+Given
+  namespace test {}
+  namespace alias = ::test;
+namespaceAliasDecl()
+  matches "namespace alias" but not "namespace test"
+
+ + Matcher<Decl>namespaceDeclMatcher<NamespaceDecl>...
Matches a declaration of a namespace.
 
@@ -288,6 +316,25 @@ namespaceDecl()
 
+Matcher<Decl>nonTypeTemplateParmDeclMatcher<NonTypeTemplateParmDecl>... +
Matches non-type template parameter declarations.
+
+Given
+  template <typename T, int N> struct C {};
+nonTypeTemplateParmDecl()
+  matches 'N', but not 'T'.
+
+ + +Matcher<Decl>objcInterfaceDeclMatcher<ObjCInterfaceDecl>... +
Matches Objective-C interface declarations.
+
+Example matches Foo
+  @interface Foo
+  @end
+
+ + Matcher<Decl>parmVarDeclMatcher<ParmVarDecl>...
Matches parameter variable declarations.
 
@@ -298,12 +345,39 @@ parmVarDecl()
 
-Matcher<Decl>recordDeclMatcher<CXXRecordDecl>... -
Matches C++ class declarations.
+Matcher<Decl>recordDeclMatcher<RecordDecl>...
+
Matches class, struct, and union declarations.
 
-Example matches X, Z
+Example matches X, Z, U, and S
   class X;
   template<class T> class Z {};
+  struct S {};
+  union U {};
+
+ + +Matcher<Decl>staticAssertDeclMatcher<StaticAssertDecl>... +
Matches a C++ static_assert declaration.
+
+Example:
+  staticAssertExpr()
+matches
+  static_assert(sizeof(S) == sizeof(int))
+in
+  struct S {
+    int x;
+  };
+  static_assert(sizeof(S) == sizeof(int));
+
+ + +Matcher<Decl>templateTypeParmDeclMatcher<TemplateTypeParmDecl>... +
Matches template type parameter declarations.
+
+Given
+  template <typename T, int N> struct C {};
+templateTypeParmDecl()
+  matches 'T', but not 'N'.
 
@@ -330,6 +404,22 @@ typedefDecl()
+Matcher<Decl>unresolvedUsingTypenameDeclMatcher<UnresolvedUsingTypenameDecl>... +
Matches unresolved using value declarations that involve the
+typename.
+
+Given
+  template <typename T>
+  struct Base { typedef T Foo; };
+
+  template<typename T>
+  struct S : private Base<T> {
+    using typename Base<T>::Foo;
+  };
+unresolvedUsingTypenameDecl()
+  matches using Base<T>::Foo 
+ + Matcher<Decl>unresolvedUsingValueDeclMatcher<UnresolvedUsingValueDecl>...
Matches unresolved using value declarations.
 
@@ -407,14 +497,6 @@ nestedNameSpecifier()
 
-Matcher<Stmt>CUDAKernelCallExprMatcher<CUDAKernelCallExpr>... -
Matches CUDA kernel call expression.
-
-Example matches,
-  kernel<<<i,j>>>();
-
- - Matcher<Stmt>arraySubscriptExprMatcher<ArraySubscriptExpr>...
Matches array subscript expressions.
 
@@ -443,24 +525,6 @@ Example matches a || b
 
-Matcher<Stmt>bindTemporaryExprMatcher<CXXBindTemporaryExpr>... -
Matches nodes where temporaries are created.
-
-Example matches FunctionTakesString(GetStringByValue())
-    (matcher = bindTemporaryExpr())
-  FunctionTakesString(GetStringByValue());
-  FunctionTakesStringByPointer(GetStringPointer());
-
- - -Matcher<Stmt>boolLiteralMatcher<CXXBoolLiteralExpr>... -
Matches bool literals.
-
-Example matches true
-  true
-
- - Matcher<Stmt>breakStmtMatcher<BreakStmt>...
Matches break statements.
 
@@ -512,15 +576,6 @@ but does not match
 
-Matcher<Stmt>catchStmtMatcher<CXXCatchStmt>... -
Matches catch statements.
-
-  try {} catch(int i) {}
-catchStmt()
-  matches 'catch(int i)'
-
- - Matcher<Stmt>characterLiteralMatcher<CharacterLiteral>...
Matches character literals (also matches wchar_t).
 
@@ -556,8 +611,53 @@ Example matches a ? b : c
 
-Matcher<Stmt>constCastExprMatcher<CXXConstCastExpr>... -
Matches a const_cast expression.
+Matcher<Stmt>continueStmtMatcher<ContinueStmt>...
+
Matches continue statements.
+
+Given
+  while (true) { continue; }
+continueStmt()
+  matches 'continue'
+
+ + +Matcher<Stmt>cudaKernelCallExprMatcher<CUDAKernelCallExpr>... +
Matches CUDA kernel call expression.
+
+Example matches,
+  kernel<<<i,j>>>();
+
+ + +Matcher<Stmt>cxxBindTemporaryExprMatcher<CXXBindTemporaryExpr>... +
Matches nodes where temporaries are created.
+
+Example matches FunctionTakesString(GetStringByValue())
+    (matcher = cxxBindTemporaryExpr())
+  FunctionTakesString(GetStringByValue());
+  FunctionTakesStringByPointer(GetStringPointer());
+
+ + +Matcher<Stmt>cxxBoolLiteralMatcher<CXXBoolLiteralExpr>... +
Matches bool literals.
+
+Example matches true
+  true
+
+ + +Matcher<Stmt>cxxCatchStmtMatcher<CXXCatchStmt>... +
Matches catch statements.
+
+  try {} catch(int i) {}
+cxxCatchStmt()
+  matches 'catch(int i)'
+
+ + +Matcher<Stmt>cxxConstCastExprMatcher<CXXConstCastExpr>... +
Matches a const_cast expression.
 
 Example: Matches const_cast<int*>(&r) in
   int n = 42;
@@ -566,11 +666,11 @@ Example: Matches const_cast<int*>(&r) in
 
-Matcher<Stmt>constructExprMatcher<CXXConstructExpr>... -
Matches constructor call expressions (including implicit ones).
+Matcher<Stmt>cxxConstructExprMatcher<CXXConstructExpr>...
+
Matches constructor call expressions (including implicit ones).
 
 Example matches string(ptr, n) and ptr within arguments of f
-    (matcher = constructExpr())
+    (matcher = cxxConstructExpr())
   void f(const string &a, const string &b);
   char *ptr;
   int n;
@@ -578,13 +678,172 @@ Example matches string(ptr, n) and ptr within arguments of f
 
-Matcher<Stmt>continueStmtMatcher<ContinueStmt>... -
Matches continue statements.
+Matcher<Stmt>cxxDefaultArgExprMatcher<CXXDefaultArgExpr>...
+
Matches the value of a default argument at the call site.
+
+Example matches the CXXDefaultArgExpr placeholder inserted for the
+    default value of the second parameter in the call expression f(42)
+    (matcher = cxxDefaultArgExpr())
+  void f(int x, int y = 0);
+  f(42);
+
+ + +Matcher<Stmt>cxxDeleteExprMatcher<CXXDeleteExpr>... +
Matches delete expressions.
 
 Given
-  while (true) { continue; }
-continueStmt()
-  matches 'continue'
+  delete X;
+cxxDeleteExpr()
+  matches 'delete X'.
+
+ + +Matcher<Stmt>cxxDynamicCastExprMatcher<CXXDynamicCastExpr>... +
Matches a dynamic_cast expression.
+
+Example:
+  cxxDynamicCastExpr()
+matches
+  dynamic_cast<D*>(&b);
+in
+  struct B { virtual ~B() {} }; struct D : B {};
+  B b;
+  D* p = dynamic_cast<D*>(&b);
+
+ + +Matcher<Stmt>cxxForRangeStmtMatcher<CXXForRangeStmt>... +
Matches range-based for statements.
+
+cxxForRangeStmt() matches 'for (auto a : i)'
+  int i[] =  {1, 2, 3}; for (auto a : i);
+  for(int j = 0; j < 5; ++j);
+
+ + +Matcher<Stmt>cxxFunctionalCastExprMatcher<CXXFunctionalCastExpr>... +
Matches functional cast expressions
+
+Example: Matches Foo(bar);
+  Foo f = bar;
+  Foo g = (Foo) bar;
+  Foo h = Foo(bar);
+
+ + +Matcher<Stmt>cxxMemberCallExprMatcher<CXXMemberCallExpr>... +
Matches member call expressions.
+
+Example matches x.y()
+  X x;
+  x.y();
+
+ + +Matcher<Stmt>cxxNewExprMatcher<CXXNewExpr>... +
Matches new expressions.
+
+Given
+  new X;
+cxxNewExpr()
+  matches 'new X'.
+
+ + +Matcher<Stmt>cxxNullPtrLiteralExprMatcher<CXXNullPtrLiteralExpr>... +
Matches nullptr literal.
+
+ + +Matcher<Stmt>cxxOperatorCallExprMatcher<CXXOperatorCallExpr>... +
Matches overloaded operator calls.
+
+Note that if an operator isn't overloaded, it won't match. Instead, use
+binaryOperator matcher.
+Currently it does not match operators such as new delete.
+FIXME: figure out why these do not match?
+
+Example matches both operator<<((o << b), c) and operator<<(o, b)
+    (matcher = cxxOperatorCallExpr())
+  ostream &operator<< (ostream &out, int i) { };
+  ostream &o; int b = 1, c = 1;
+  o << b << c;
+
+ + +Matcher<Stmt>cxxReinterpretCastExprMatcher<CXXReinterpretCastExpr>... +
Matches a reinterpret_cast expression.
+
+Either the source expression or the destination type can be matched
+using has(), but hasDestinationType() is more specific and can be
+more readable.
+
+Example matches reinterpret_cast<char*>(&p) in
+  void* p = reinterpret_cast<char*>(&p);
+
+ + +Matcher<Stmt>cxxStaticCastExprMatcher<CXXStaticCastExpr>... +
Matches a C++ static_cast expression.
+
+hasDestinationType
+reinterpretCast
+
+Example:
+  cxxStaticCastExpr()
+matches
+  static_cast<long>(8)
+in
+  long eight(static_cast<long>(8));
+
+ + +Matcher<Stmt>cxxTemporaryObjectExprMatcher<CXXTemporaryObjectExpr>... +
Matches functional cast expressions having N != 1 arguments
+
+Example: Matches Foo(bar, bar)
+  Foo h = Foo(bar, bar);
+
+ + +Matcher<Stmt>cxxThisExprMatcher<CXXThisExpr>... +
Matches implicit and explicit this expressions.
+
+Example matches the implicit this expression in "return i".
+    (matcher = cxxThisExpr())
+struct foo {
+  int i;
+  int f() { return i; }
+};
+
+ + +Matcher<Stmt>cxxThrowExprMatcher<CXXThrowExpr>... +
Matches throw expressions.
+
+  try { throw 5; } catch(int i) {}
+cxxThrowExpr()
+  matches 'throw 5'
+
+ + +Matcher<Stmt>cxxTryStmtMatcher<CXXTryStmt>... +
Matches try statements.
+
+  try {} catch(int i) {}
+cxxTryStmt()
+  matches 'try {}'
+
+ + +Matcher<Stmt>cxxUnresolvedConstructExprMatcher<CXXUnresolvedConstructExpr>... +
Matches unresolved constructor call expressions.
+
+Example matches T(t) in return statement of f
+    (matcher = cxxUnresolvedConstructExpr())
+  template <typename T>
+  void f(const T& t) { return T(t); }
 
@@ -607,17 +866,6 @@ declStmt()
-Matcher<Stmt>defaultArgExprMatcher<CXXDefaultArgExpr>... -
Matches the value of a default argument at the call site.
-
-Example matches the CXXDefaultArgExpr placeholder inserted for the
-    default value of the second parameter in the call expression f(42)
-    (matcher = defaultArgExpr())
-  void f(int x, int y = 0);
-  f(42);
-
- - Matcher<Stmt>defaultStmtMatcher<DefaultStmt>...
Matches default statements inside switch statements.
 
@@ -628,16 +876,6 @@ defaultStmt()
 
-Matcher<Stmt>deleteExprMatcher<CXXDeleteExpr>... -
Matches delete expressions.
-
-Given
-  delete X;
-deleteExpr()
-  matches 'delete X'.
-
- - Matcher<Stmt>doStmtMatcher<DoStmt>...
Matches do statements.
 
@@ -648,20 +886,6 @@ doStmt()
 
-Matcher<Stmt>dynamicCastExprMatcher<CXXDynamicCastExpr>... -
Matches a dynamic_cast expression.
-
-Example:
-  dynamicCastExpr()
-matches
-  dynamic_cast<D*>(&b);
-in
-  struct B { virtual ~B() {} }; struct D : B {};
-  B b;
-  D* p = dynamic_cast<D*>(&b);
-
- - Matcher<Stmt>explicitCastExprMatcher<ExplicitCastExpr>...
Matches explicit cast expressions.
 
@@ -709,15 +933,6 @@ Does not match implicit conversions such as
 
-Matcher<Stmt>forRangeStmtMatcher<CXXForRangeStmt>... -
Matches range-based for statements.
-
-forRangeStmt() matches 'for (auto a : i)'
-  int i[] =  {1, 2, 3}; for (auto a : i);
-  for(int j = 0; j < 5; ++j);
-
- - Matcher<Stmt>forStmtMatcher<ForStmt>...
Matches for statements.
 
@@ -727,13 +942,8 @@ Example matches 'for (;;) {}'
 
-Matcher<Stmt>functionalCastExprMatcher<CXXFunctionalCastExpr>... -
Matches functional cast expressions
-
-Example: Matches Foo(bar);
-  Foo f = bar;
-  Foo g = (Foo) bar;
-  Foo h = Foo(bar);
+Matcher<Stmt>gnuNullExprMatcher<GNUNullExpr>...
+
Matches GNU __null expression.
 
@@ -819,15 +1029,6 @@ but does not match
-Matcher<Stmt>memberCallExprMatcher<CXXMemberCallExpr>... -
Matches member call expressions.
-
-Example matches x.y()
-  X x;
-  x.y();
-
- - Matcher<Stmt>memberExprMatcher<MemberExpr>...
Matches member expressions.
 
@@ -841,21 +1042,6 @@ memberExpr()
 
-Matcher<Stmt>newExprMatcher<CXXNewExpr>... -
Matches new expressions.
-
-Given
-  new X;
-newExpr()
-  matches 'new X'.
-
- - -Matcher<Stmt>nullPtrLiteralExprMatcher<CXXNullPtrLiteralExpr>... -
Matches nullptr literal.
-
- - Matcher<Stmt>nullStmtMatcher<NullStmt>...
Matches null statements.
 
@@ -865,31 +1051,14 @@ nullStmt()
 
-Matcher<Stmt>operatorCallExprMatcher<CXXOperatorCallExpr>... -
Matches overloaded operator calls.
+Matcher<Stmt>objcMessageExprMatcher<ObjCMessageExpr>...
+
Matches ObjectiveC Message invocation expressions.
 
-Note that if an operator isn't overloaded, it won't match. Instead, use
-binaryOperator matcher.
-Currently it does not match operators such as new delete.
-FIXME: figure out why these do not match?
-
-Example matches both operator<<((o << b), c) and operator<<(o, b)
-    (matcher = operatorCallExpr())
-  ostream &operator<< (ostream &out, int i) { };
-  ostream &o; int b = 1, c = 1;
-  o << b << c;
-
- - -Matcher<Stmt>reinterpretCastExprMatcher<CXXReinterpretCastExpr>... -
Matches a reinterpret_cast expression.
-
-Either the source expression or the destination type can be matched
-using has(), but hasDestinationType() is more specific and can be
-more readable.
-
-Example matches reinterpret_cast<char*>(&p) in
-  void* p = reinterpret_cast<char*>(&p);
+The innermost message send invokes the "alloc" class method on the
+NSString class, while the outermost message send invokes the
+"initWithString" instance method on the object returned from
+NSString's "alloc". This matcher should match both message sends.
+  [[NSString alloc] initWithString:@"Hello"]
 
@@ -903,21 +1072,6 @@ returnStmt()
-Matcher<Stmt>staticCastExprMatcher<CXXStaticCastExpr>... -
Matches a C++ static_cast expression.
-
-hasDestinationType
-reinterpretCast
-
-Example:
-  staticCastExpr()
-matches
-  static_cast<long>(8)
-in
-  long eight(static_cast<long>(8));
-
- - Matcher<Stmt>stmtMatcher<Stmt>...
Matches statements.
 
@@ -968,44 +1122,6 @@ switchStmt()
 
-Matcher<Stmt>temporaryObjectExprMatcher<CXXTemporaryObjectExpr>... -
Matches functional cast expressions having N != 1 arguments
-
-Example: Matches Foo(bar, bar)
-  Foo h = Foo(bar, bar);
-
- - -Matcher<Stmt>thisExprMatcher<CXXThisExpr>... -
Matches implicit and explicit this expressions.
-
-Example matches the implicit this expression in "return i".
-    (matcher = thisExpr())
-struct foo {
-  int i;
-  int f() { return i; }
-};
-
- - -Matcher<Stmt>throwExprMatcher<CXXThrowExpr>... -
Matches throw expressions.
-
-  try { throw 5; } catch(int i) {}
-throwExpr()
-  matches 'throw 5'
-
- - -Matcher<Stmt>tryStmtMatcher<CXXTryStmt>... -
Matches try statements.
-
-  try {} catch(int i) {}
-tryStmt()
-  matches 'try {}'
-
- - Matcher<Stmt>unaryExprOrTypeTraitExprMatcher<UnaryExprOrTypeTraitExpr>...
Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
 
@@ -1025,16 +1141,6 @@ Example matches !a
 
-Matcher<Stmt>unresolvedConstructExprMatcher<CXXUnresolvedConstructExpr>... -
Matches unresolved constructor call expressions.
-
-Example matches T(t) in return statement of f
-    (matcher = unresolvedConstructExpr())
-  template <typename T>
-  void f(const T& t) { return T(t); }
-
- - Matcher<Stmt>userDefinedLiteralMatcher<UserDefinedLiteral>...
Matches user defined literal operator call.
 
@@ -1148,6 +1254,18 @@ constantArrayType()
 
+Matcher<Type>decayedTypeMatcher<DecayedType>... +
Matches decayed type
+Example matches i[] in declaration of f.
+    (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
+Example matches i[1].
+    (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())))))
+  void f(int i[]) {
+    i[1] = 0;
+  }
+
+ + Matcher<Type>dependentSizedArrayTypeMatcher<DependentSizedArrayType>...
Matches C++ arrays whose size is a value-dependent expression.
 
@@ -1204,6 +1322,18 @@ incompleteArrayType()
 
+Matcher<Type>injectedClassNameTypeMatcher<InjectedClassNameType>... +
Matches injected class name types.
+
+Example matches S s, but not S<T> s.
+    (matcher = parmVarDecl(hasType(injectedClassNameType())))
+  template <typename T> struct S {
+    void f(S s);
+    void g(S<T> s);
+  };
+
+ + Matcher<Type>lValueReferenceTypeMatcher<LValueReferenceType>...
Matches lvalue reference types.
 
@@ -1231,6 +1361,21 @@ memberPointerType()
 
+Matcher<Type>objcObjectPointerTypeMatcher<ObjCObjectPointerType>... +
Matches an Objective-C object pointer type, which is different from
+a pointer type, despite being syntactically similar.
+
+Given
+  int *a;
+
+  @interface Foo
+  @end
+  Foo *f;
+pointerType()
+  matches "Foo *f", but does not match "int *a".
+
+ + Matcher<Type>parenTypeMatcher<ParenType>...
Matches ParenType nodes.
 
@@ -1244,14 +1389,19 @@ array_of_ptrs.
 
 
 Matcher<Type>pointerTypeMatcher<PointerType>...
-
Matches pointer types.
+
Matches pointer types, but does not match Objective-C object pointer
+types.
 
 Given
   int *a;
   int &b = *a;
   int c = 5;
+
+  @interface Foo
+  @end
+  Foo *f;
 pointerType()
-  matches "int *a"
+  matches "int *a", but does not match "Foo *f".
 
@@ -1303,6 +1453,20 @@ referenceType() matches the types of b, c, d, e, and f.
+Matcher<Type>substTemplateTypeParmTypeMatcher<SubstTemplateTypeParmType>... +
Matches types that represent the result of substituting a type for a
+template type parameter.
+
+Given
+  template <typename T>
+  void F(T t) {
+    int i = 1 + t;
+  }
+
+substTemplateTypeParmType() matches the type of 't' but not '1'
+
+ + Matcher<Type>templateSpecializationTypeMatcher<TemplateSpecializationType>...
Matches template specialization types.
 
@@ -1318,6 +1482,15 @@ instantiation in A and the type of the variable declaration in B.
 
+Matcher<Type>templateTypeParmTypeMatcher<TemplateTypeParmType>... +
Matches template type parameter types.
+
+Example matches T, but not int.
+    (matcher = templateTypeParmType())
+  template <typename T> void f(int i);
+
+ + Matcher<Type>typeMatcher<Type>...
Matches Types in the clang AST.
 
@@ -1407,7 +1580,7 @@ Usable as: Any Matcher Matcher<*>unlessMatcher<*>
Matches if the provided matcher does not match.
 
-Example matches Y (matcher = recordDecl(unless(hasName("X"))))
+Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
   class X {};
   class Y {};
 
@@ -1427,21 +1600,27 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
 Matcher<CXXBoolLiteral>equalsValueT  Value
 
Matches literals that are equal to the given value.
 
-Example matches true (matcher = boolLiteral(equals(true)))
+Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
 Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
            Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
 
-Matcher<CXXCatchStmt>isCatchAll -
Matches a C++ catch statement that has a handler that catches any exception type.
 
-Example matches catch(...) (matcher = catchStmt(isCatchAll()))
+Matcher<CXXCatchStmt>isCatchAll
+
Matches a C++ catch statement that has a catch-all handler.
+
+Given
   try {
-    // ...
-  } catch(...) {
+    ...
+  } catch (int) {
+    ...
+  } catch (...) {
+    ...
   }
+endcode
+cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
 
@@ -1460,6 +1639,113 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
+Matcher<CXXConstructorDecl>isCopyConstructor +
Matches constructor declarations that are copy constructors.
+
+Given
+  struct S {
+    S(); #1
+    S(const S &); #2
+    S(S &&); #3
+  };
+cxxConstructorDecl(isCopyConstructor()) will match #2, but not #1 or #3.
+
+ + +Matcher<CXXConstructorDecl>isDefaultConstructor +
Matches constructor declarations that are default constructors.
+
+Given
+  struct S {
+    S(); #1
+    S(const S &); #2
+    S(S &&); #3
+  };
+cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3.
+
+ + +Matcher<CXXConstructorDecl>isExplicit +
Matches constructor and conversion declarations that are marked with
+the explicit keyword.
+
+Given
+  struct S {
+    S(int); #1
+    explicit S(double); #2
+    operator int(); #3
+    explicit operator bool(); #4
+  };
+cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+cxxConversionDecl(isExplicit()) will match #4, but not #3.
+
+ + +Matcher<CXXConstructorDecl>isMoveConstructor +
Matches constructor declarations that are move constructors.
+
+Given
+  struct S {
+    S(); #1
+    S(const S &); #2
+    S(S &&); #3
+  };
+cxxConstructorDecl(isMoveConstructor()) will match #3, but not #1 or #2.
+
+ + +Matcher<CXXConversionDecl>isExplicit +
Matches constructor and conversion declarations that are marked with
+the explicit keyword.
+
+Given
+  struct S {
+    S(int); #1
+    explicit S(double); #2
+    operator int(); #3
+    explicit operator bool(); #4
+  };
+cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+cxxConversionDecl(isExplicit()) will match #4, but not #3.
+
+ + +Matcher<CXXCtorInitializer>isBaseInitializer +
Matches a constructor initializer if it is initializing a base, as
+opposed to a member.
+
+Given
+  struct B {};
+  struct D : B {
+    int I;
+    D(int i) : I(i) {}
+  };
+  struct E : B {
+    E() : B() {}
+  };
+cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer()))
+  will match E(), but not match D(int).
+
+ + +Matcher<CXXCtorInitializer>isMemberInitializer +
Matches a constructor initializer if it is initializing a member, as
+opposed to a base.
+
+Given
+  struct B {};
+  struct D : B {
+    int I;
+    D(int i) : I(i) {}
+  };
+  struct E : B {
+    E() : B() {}
+  };
+cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer()))
+  will match D(int), but not match E().
+
+ + Matcher<CXXCtorInitializer>isWritten
Matches a constructor initializer if it is explicitly written in
 code (as opposed to implicitly added by the compiler).
@@ -1470,7 +1756,7 @@ Given
     Foo(int) : foo_("A") { }
     string foo_;
   };
-constructorDecl(hasAnyConstructorInitializer(isWritten()))
+cxxConstructorDecl(hasAnyConstructorInitializer(isWritten()))
   will match Foo(int), but not Foo()
 
@@ -1484,7 +1770,39 @@ struct A { void bar(); }; -methodDecl(isConst()) matches A::foo() but not A::bar() +cxxMethodDecl(isConst()) matches A::foo() but not A::bar() +
+ + +Matcher<CXXMethodDecl>isCopyAssignmentOperator +
Matches if the given method declaration declares a copy assignment
+operator.
+
+Given
+struct A {
+  A &operator=(const A &);
+  A &operator=(A &&);
+};
+
+cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
+the second one.
+
+ + +Matcher<CXXMethodDecl>isFinal +
Matches if the given method or class declaration is final.
+
+Given:
+  class A final {};
+
+  struct B {
+    virtual void f();
+  };
+
+  struct C : B {
+    void f() final;
+  };
+matches A and C::f, but not B, C, or B::f
 
@@ -1540,9 +1858,10 @@ Given: A a; a << a; <-- This matches -operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified -line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches -the declaration of A. +cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the +specified line and +cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))) +matches the declaration of A. Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
@@ -1567,6 +1886,23 @@ Usable as: Matcher<CXXRecordDecl>isFinal +
Matches if the given method or class declaration is final.
+
+Given:
+  class A final {};
+
+  struct B {
+    virtual void f();
+  };
+
+  struct C : B {
+    void f() final;
+  };
+matches A and C::f, but not B, C, or B::f
+
+ + Matcher<CXXRecordDecl>isSameOrDerivedFromstd::string BaseName
Overloaded method as shortcut for
 isSameOrDerivedFrom(hasName(...)).
@@ -1581,13 +1917,13 @@ Given
   template <typename T> class X {}; class A {}; X<A> x;
 or
   template <typename T> class X {}; class A {}; template class X<A>;
-recordDecl(hasName("::X"), isTemplateInstantiation())
+cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
   matches the template instantiation of X<A>.
 
 But given
   template <typename T>  class X {}; class A {};
   template <> class X<A> {}; X<A> x;
-recordDecl(hasName("::X"), isTemplateInstantiation())
+cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
   does not match, as X<A> is an explicit template specialization.
 
 Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
@@ -1607,7 +1943,7 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
 Matcher<CharacterLiteral>equalsValueT  Value
 
Matches literals that are equal to the given value.
 
-Example matches true (matcher = boolLiteral(equals(true)))
+Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
 Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
@@ -1670,7 +2006,7 @@ Matches a node if it equals the node previously bound to ID.
 
 Given
   class X { int a; int b; };
-recordDecl(
+cxxRecordDecl(
     has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
     has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
   matches the class X, as a and b have the same type.
@@ -1692,7 +2028,8 @@ and reference to that variable declaration within a compound statement.
 Given
   __attribute__((device)) void f() { ... }
 decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
-f.
+f. If the matcher is use from clang-query, attr::Kind parameter should be
+passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
 
@@ -1701,7 +2038,7 @@ f. partially matching a given regex. Example matches Y but not X - (matcher = recordDecl(isExpansionInFileMatching("AST.*")) + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) #include "ASTMatcher.h" class X {}; ASTMatcher.h: @@ -1714,7 +2051,8 @@ Usable as: Matcher<Decl>isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
 
-Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
+Example matches X but not Y
+  (matcher = cxxRecordDecl(isExpansionInMainFile())
   #include <Y.h>
   class X {};
 Y.h:
@@ -1728,7 +2066,7 @@ Usable as: Matcher<
Matches AST nodes that were expanded within system-header-files.
 
 Example matches Y but not X
-    (matcher = recordDecl(isExpansionInSystemHeader())
+    (matcher = cxxRecordDecl(isExpansionInSystemHeader())
   #include <SystemHeader.h>
   class X {};
 SystemHeader.h:
@@ -1789,7 +2127,7 @@ fieldDecl(isPublic())
 Matcher<FloatingLiteral>equalsValueT  Value
 
Matches literals that are equal to the given value.
 
-Example matches true (matcher = boolLiteral(equals(true)))
+Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
 Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
@@ -1809,14 +2147,28 @@ Given:
   A a;
   a << a;   <-- This matches
 
-operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified
-line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
-the declaration of A.
+cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the
+specified line and
+cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")))
+matches the declaration of A.
 
 Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
 
+Matcher<FunctionDecl>isConstexpr +
Matches constexpr variable and function declarations.
+
+Given:
+  constexpr int foo = 42;
+  constexpr int bar();
+varDecl(isConstexpr())
+  matches the declaration of foo.
+functionDecl(isConstexpr())
+  matches the declaration of bar.
+
+ + Matcher<FunctionDecl>isDefinition
Matches if a declaration has a body attached.
 
@@ -1869,6 +2221,35 @@ functionDecl(isExternC())
 
+Matcher<FunctionDecl>isInline +
Matches function and namespace declarations that are marked with
+the inline keyword.
+
+Given
+  inline void f();
+  void g();
+  namespace n {
+  inline namespace m {}
+  }
+functionDecl(isInline()) will match ::f().
+namespaceDecl(isInline()) will match n::m.
+
+ + +Matcher<FunctionDecl>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())
+  matches the declarations of g, and h, but not f, i or j.
+
+ + Matcher<FunctionDecl>isTemplateInstantiation
Matches template instantiations of function, class, or static
 member variable template instantiations.
@@ -1877,19 +2258,31 @@ Given
   template <typename T> class X {}; class A {}; X<A> x;
 or
   template <typename T> class X {}; class A {}; template class X<A>;
-recordDecl(hasName("::X"), isTemplateInstantiation())
+cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
   matches the template instantiation of X<A>.
 
 But given
   template <typename T>  class X {}; class A {};
   template <> class X<A> {}; X<A> x;
-recordDecl(hasName("::X"), isTemplateInstantiation())
+cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
   does not match, as X<A> is an explicit template specialization.
 
 Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
 
+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
+compiled in C mode.
+  void f(...);
+  void g(int);
+  template <typename... Ts> void h(Ts...);
+  void i();
+
+ + Matcher<FunctionDecl>parameterCountIsunsigned N
Matches FunctionDecls that have a specific parameter count.
 
@@ -1904,7 +2297,7 @@ functionDecl(parameterCountIs(2))
 Matcher<IntegerLiteral>equalsValueT  Value
 
Matches literals that are equal to the given value.
 
-Example matches true (matcher = boolLiteral(equals(true)))
+Example matches true (matcher = cxxBoolLiteral(equals(true)))
   true
 
 Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
@@ -1960,13 +2353,113 @@ Example matches X (regexp is one of "::X", "^foo::.*X", among others)
 
+Matcher<NamespaceDecl>isAnonymous +
Matches anonymous namespace declarations.
+
+Given
+  namespace n {
+  namespace {} #1
+  }
+namespaceDecl(isAnonymous()) will match #1 but not ::n.
+
+ + +Matcher<NamespaceDecl>isInline +
Matches function and namespace declarations that are marked with
+the inline keyword.
+
+Given
+  inline void f();
+  void g();
+  namespace n {
+  inline namespace m {}
+  }
+functionDecl(isInline()) will match ::f().
+namespaceDecl(isInline()) will match n::m.
+
+ + +Matcher<ObjCMessageExpr>argumentCountIsunsigned N +
Checks that a call expression or a constructor call expression has
+a specific number of arguments (including absent default arguments).
+
+Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
+  void f(int x, int y);
+  f(0, 0);
+
+ + +Matcher<ObjCMessageExpr>hasKeywordSelector +
Matches when the selector is a keyword selector
+
+objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
+message expression in
+
+  UIWebView *webView = ...;
+  CGRect bodyFrame = webView.frame;
+  bodyFrame.size.height = self.bodyContentHeight;
+  webView.frame = bodyFrame;
+      ^---- matches here
+
+ + +Matcher<ObjCMessageExpr>hasNullSelector +
Matches when the selector is the empty selector
+
+Matches only when the selector of the objCMessageExpr is NULL. This may
+represent an error condition in the tree!
+
+ + +Matcher<ObjCMessageExpr>hasSelectorstd::string BaseName +
Matches when BaseName == Selector.getAsString()
+
+ matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
+ matches the outer message expr in the code below, but NOT the message
+ invocation for self.bodyView.
+    [self.bodyView loadHTMLString:html baseURL:NULL];
+
+ + +Matcher<ObjCMessageExpr>hasUnarySelector +
Matches when the selector is a Unary Selector
+
+ matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
+ matches self.bodyView in the code below, but NOT the outer message
+ invocation of "loadHTMLString:baseURL:".
+    [self.bodyView loadHTMLString:html baseURL:NULL];
+
+ + +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
+ invocation for self.bodyView.
+    [self.bodyView loadHTMLString:html baseURL:NULL];
+
+ + +Matcher<ObjCMessageExpr>numSelectorArgsunsigned N +
Matches when the selector has the specified number of arguments
+
+ matcher = objCMessageExpr(numSelectorArgs(0));
+ matches self.bodyView in the code below
+
+ matcher = objCMessageExpr(numSelectorArgs(2));
+ matches the invocation of "loadHTMLString:baseURL:" but not that
+ of self.bodyView
+    [self.bodyView loadHTMLString:html baseURL:NULL];
+
+ + Matcher<QualType>asStringstd::string Name
Matches if the matched type is represented by the given string.
 
 Given
   class Y { public: void x(); };
   void z() { Y* y; y->x(); }
-callExpr(on(hasType(asString("class Y *"))))
+cxxMemberCallExpr(on(hasType(asString("class Y *"))))
   matches y->x()
 
@@ -1978,7 +2471,7 @@ Matches a node if it equals the node previously bound to ID. Given class X { int a; int b; }; -recordDecl( +cxxRecordDecl( has(fieldDecl(hasName("a"), hasType(type().bind("t")))), has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) matches the class X, as a and b have the same type. @@ -2009,6 +2502,18 @@ i is const-qualified but the qualifier is not local.
+Matcher<QualType>isAnyCharacter +
Matches QualType nodes that are of character type.
+
+Given
+  void a(char);
+  void b(wchar_t);
+  void c(double);
+functionDecl(hasAnyParameter(hasType(isAnyCharacter())))
+matches "a(char)", "b(wchar_t)", but not "c(double)".
+
+ + Matcher<QualType>isConstQualified
Matches QualType nodes that are const-qualified, i.e., that
 include "top-level" const.
@@ -2038,6 +2543,53 @@ matches "a(int)", "b(long)", but not "c(double)".
 
+Matcher<QualType>isVolatileQualified +
Matches QualType nodes that are volatile-qualified, i.e., that
+include "top-level" volatile.
+
+Given
+  void a(int);
+  void b(int volatile);
+  void c(volatile int);
+  void d(volatile int*);
+  void e(int volatile) {};
+functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
+  matches "void b(int volatile)", "void c(volatile int)" and
+  "void e(int volatile) {}". It does not match d as there
+  is no top-level volatile on the parameter type "volatile int *".
+
+ + +Matcher<RecordDecl>isClass +
Matches RecordDecl object that are spelled with "class."
+
+Example matches C, but not S or U.
+  struct S {};
+  class C {};
+  union U {};
+
+ + +Matcher<RecordDecl>isStruct +
Matches RecordDecl object that are spelled with "struct."
+
+Example matches S, but not C or U.
+  struct S {};
+  class C {};
+  union U {};
+
+ + +Matcher<RecordDecl>isUnion +
Matches RecordDecl object that are spelled with "union."
+
+Example matches U, but not C or S.
+  struct S {};
+  class C {};
+  union U {};
+
+ + Matcher<Stmt>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
@@ -2045,7 +2597,7 @@ Matches a node if it equals the node previously bound to ID.
 
 Given
   class X { int a; int b; };
-recordDecl(
+cxxRecordDecl(
     has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
     has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
   matches the class X, as a and b have the same type.
@@ -2066,7 +2618,7 @@ and reference to that variable declaration within a compound statement.
 partially matching a given regex.
 
 Example matches Y but not X
-    (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
+    (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
   #include "ASTMatcher.h"
   class X {};
 ASTMatcher.h:
@@ -2079,7 +2631,8 @@ Usable as: Matcher<Stmt>isExpansionInMainFile
 
Matches AST nodes that were expanded within the main-file.
 
-Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
+Example matches X but not Y
+  (matcher = cxxRecordDecl(isExpansionInMainFile())
   #include <Y.h>
   class X {};
 Y.h:
@@ -2093,7 +2646,7 @@ Usable as: Matcher<
Matches AST nodes that were expanded within system-header-files.
 
 Example matches Y but not X
-    (matcher = recordDecl(isExpansionInSystemHeader())
+    (matcher = cxxRecordDecl(isExpansionInSystemHeader())
   #include <SystemHeader.h>
   class X {};
 SystemHeader.h:
@@ -2163,7 +2716,7 @@ classTemplateSpecializationDecl(templateArgumentCountIs(1))
 partially matching a given regex.
 
 Example matches Y but not X
-    (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
+    (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
   #include "ASTMatcher.h"
   class X {};
 ASTMatcher.h:
@@ -2176,7 +2729,8 @@ Usable as: Matcher<TypeLoc>isExpansionInMainFile
 
Matches AST nodes that were expanded within the main-file.
 
-Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
+Example matches X but not Y
+  (matcher = cxxRecordDecl(isExpansionInMainFile())
   #include <Y.h>
   class X {};
 Y.h:
@@ -2190,7 +2744,7 @@ Usable as: Matcher<
Matches AST nodes that were expanded within system-header-files.
 
 Example matches Y but not X
-    (matcher = recordDecl(isExpansionInSystemHeader())
+    (matcher = cxxRecordDecl(isExpansionInSystemHeader())
   #include <SystemHeader.h>
   class X {};
 SystemHeader.h:
@@ -2200,6 +2754,16 @@ Usable as: Matcher<Type>booleanType
+
Matches type bool.
+
+Given
+ struct S { bool func(); };
+functionDecl(returns(booleanType()))
+  matches "bool func();"
+
+ + Matcher<Type>equalsBoundNodestd::string ID
Matches if a node equals a previously bound node.
 
@@ -2207,7 +2771,7 @@ Matches a node if it equals the node previously bound to ID.
 
 Given
   class X { int a; int b; };
-recordDecl(
+cxxRecordDecl(
     has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
     has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
   matches the class X, as a and b have the same type.
@@ -2253,6 +2817,20 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
 
+Matcher<VarDecl>hasAutomaticStorageDuration +
Matches a variable declaration that has automatic storage duration.
+
+Example matches x, but not y, z, or a.
+(matcher = varDecl(hasAutomaticStorageDuration())
+void f() {
+  int x;
+  static int y;
+  thread_local int z;
+}
+int a;
+
+ + Matcher<VarDecl>hasGlobalStorage
Matches a variable declaration that does not have local storage.
 
@@ -2278,6 +2856,47 @@ int z;
 
+Matcher<VarDecl>hasStaticStorageDuration +
Matches a variable declaration that has static storage duration.
+
+Example matches y and a, but not x or z.
+(matcher = varDecl(hasStaticStorageDuration())
+void f() {
+  int x;
+  static int y;
+  thread_local int z;
+}
+int a;
+
+ + +Matcher<VarDecl>hasThreadStorageDuration +
Matches a variable declaration that has thread storage duration.
+
+Example matches z, but not x, z, or a.
+(matcher = varDecl(hasThreadStorageDuration())
+void f() {
+  int x;
+  static int y;
+  thread_local int z;
+}
+int a;
+
+ + +Matcher<VarDecl>isConstexpr +
Matches constexpr variable and function declarations.
+
+Given:
+  constexpr int foo = 42;
+  constexpr int bar();
+varDecl(isConstexpr())
+  matches the declaration of foo.
+functionDecl(isConstexpr())
+  matches the declaration of bar.
+
+ + Matcher<VarDecl>isDefinition
Matches if a declaration has a body attached.
 
@@ -2293,6 +2912,19 @@ Usable as: Matcher<VarDecl>isExceptionVariable
+
Matches a variable declaration that is an exception variable from
+a C++ catch block, or an Objective-C statement.
+
+Example matches x (matcher = varDecl(isExceptionVariable())
+void f(int y) {
+  try {
+  } catch (int x) {
+  }
+}
+
+ + Matcher<VarDecl>isExplicitTemplateSpecialization
Matches explicit template specializations of function, class, or
 static member variable template instantiations.
@@ -2315,13 +2947,13 @@ Given
   template <typename T> class X {}; class A {}; X<A> x;
 or
   template <typename T> class X {}; class A {}; template class X<A>;
-recordDecl(hasName("::X"), isTemplateInstantiation())
+cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
   matches the template instantiation of X<A>.
 
 But given
   template <typename T>  class X {}; class A {};
   template <> class X<A> {}; X<A> x;
-recordDecl(hasName("::X"), isTemplateInstantiation())
+cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
   does not match, as X<A> is an explicit template specialization.
 
 Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
@@ -2383,8 +3015,8 @@ matching submatcher.
 For example, in:
   class A { int a; int b; };
 The matcher:
-  recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
-                    has(fieldDecl(hasName("b")).bind("v"))))
+  cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
+                       has(fieldDecl(hasName("b")).bind("v"))))
 will generate two results binding "v", the first of which binds
 the field declaration of a, the second the field declaration of
 b.
@@ -2398,7 +3030,7 @@ Usable as: Any Matcher
 provided matcher.
 
 Example matches X, A, B, C
-    (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X")))))
+  (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X")))))
   class X {};  Matches X, because X::X is a class of name X inside X.
   class A { class X {}; };
   class B { class C { class X {}; }; };
@@ -2409,7 +3041,9 @@ As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
 each result that matches instead of only on the first one.
 
 Note: Recursively combined ForEachDescendant can cause many matches:
-  recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl()))))
+  cxxRecordDecl(forEachDescendant(cxxRecordDecl(
+    forEachDescendant(cxxRecordDecl())
+  )))
 will match 10 times (plus injected class name matches) on:
   class A { class B { class C { class D { class E {}; }; }; }; };
 
@@ -2421,7 +3055,8 @@ Usable as: Any Matcher
 
Matches AST nodes that have child AST nodes that match the
 provided matcher.
 
-Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X")))
+Example matches X, Y
+  (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X")))
   class X {};  Matches X, because X::X is a class of name X inside X.
   class Y { class X {}; };
   class Z { class Y { class X {}; }; };  Does not match Z.
@@ -2453,7 +3088,7 @@ Usable as: Any Matcher
 provided matcher.
 
 Example matches X, Y, Z
-    (matcher = recordDecl(hasDescendant(recordDecl(hasName("X")))))
+    (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X")))))
   class X {};  Matches X, because X::X is a class of name X inside X.
   class Y { class X {}; };
   class Z { class Y { class X {}; }; };
@@ -2468,7 +3103,8 @@ Usable as: Any Matcher
 
Matches AST nodes that have child AST nodes that match the
 provided matcher.
 
-Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X")))
+Example matches X, Y
+  (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X")))
   class X {};  Matches X, because X::X is a class of name X inside X.
   class Y { class X {}; };
   class Z { class Y { class X {}; }; };  Does not match Z.
@@ -2514,6 +3150,22 @@ arraySubscriptExpression(hasIndex(integerLiteral()))
 
+Matcher<ArraySubscriptExpr>hasLHSMatcher<Expr> InnerMatcher +
Matches the left hand side of binary operator expressions.
+
+Example matches a (matcher = binaryOperator(hasLHS()))
+  a || b
+
+ + +Matcher<ArraySubscriptExpr>hasRHSMatcher<Expr> InnerMatcher +
Matches the right hand side of binary operator expressions.
+
+Example matches b (matcher = binaryOperator(hasRHS()))
+  a || b
+
+ + Matcher<ArrayTypeLoc>hasElementTypeLocMatcher<TypeLoc>
Matches arrays and C99 complex types that have a specific element
 type.
@@ -2695,7 +3347,9 @@ Usable as: Matcher<
 
@@ -2708,7 +3362,9 @@ Given
     Foo() : foo_(1) { }
     int foo_;
   };
-recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything()))))
+cxxRecordDecl(has(cxxConstructorDecl(
+  hasAnyConstructorInitializer(anything())
+)))
   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
 
@@ -2721,7 +3377,7 @@ Given Foo() : foo_(1) { } int foo_; }; -recordDecl(has(constructorDecl(hasAnyConstructorInitializer( +cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer( forField(hasName("foo_")))))) matches Foo with forField matching foo_ @@ -2736,7 +3392,7 @@ Given Foo() : foo_(1) { } int foo_; }; -recordDecl(has(constructorDecl(hasAnyConstructorInitializer( +cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer( withInitializer(integerLiteral(equals(1))))))) matches Foo with withInitializer matching (1) @@ -2783,7 +3439,8 @@ matches 'a' in Matcher<CXXMemberCallExpr>onMatcher<Expr> InnerMatcher
Matches on the implicit object argument of a member call expression.
 
-Example matches y.x() (matcher = callExpr(on(hasType(recordDecl(hasName("Y"))))))
+Example matches y.x()
+  (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))))
   class Y { public: void x(); };
   void z() { Y y; y.x(); }",
 
@@ -2811,7 +3468,7 @@ FIXME: What other kind of declarations would we need to generalize
 this to?
 
 Example matches A() in the last line
-    (matcher = constructExpr(hasDeclaration(methodDecl(
+    (matcher = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
         ofClass(hasName("A"))))))
   class A {
    public:
@@ -2828,8 +3485,8 @@ Given:
   class A { void func(); };
   class B { void member(); };
 
-recordDecl(hasMethod(hasName("func"))) matches the declaration of A
-but not B.
+cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of
+A but not B.
 
@@ -2864,7 +3521,8 @@ match Base.
Matches if the call expression's callee's declaration matches the
 given matcher.
 
-Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x")))))
+Example matches y.x() (matcher = callExpr(callee(
+                                   cxxMethodDecl(hasName("x")))))
   class Y { public: void x(); };
   void z() { Y y; y.x(); }
 
@@ -2953,7 +3611,7 @@ caseStmt(hasCaseConstant(integerLiteral()))
Matches if the cast's source expression matches the given matcher.
 
 Example: matches "a string" (matcher =
-                                 hasSourceExpression(constructExpr()))
+                                 hasSourceExpression(cxxConstructExpr()))
 class URL { URL(string); };
 URL url = "a string";
 
@@ -3034,7 +3692,7 @@ with compoundStmt()
Matches the condition expression of an if statement, for loop,
 or conditional operator.
 
-Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
@@ -3055,6 +3713,11 @@ Example matches a
+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
 matches the given matcher.
@@ -3081,8 +3744,6 @@ Usable as: Matcher<
Matches a DeclRefExpr that refers to a declaration through a
 specific using shadow declaration.
 
-FIXME: This currently only works for functions. Fix.
-
 Given
   namespace a { void f() {} }
   using a::f;
@@ -3090,7 +3751,7 @@ Given
     f();     Matches this ..
     a::f();  .. but not this.
   }
-declRefExpr(throughUsingDeclaration(anything()))
+declRefExpr(throughUsingDecl(anything()))
   matches f()
 
@@ -3158,7 +3819,7 @@ Given } } -recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the +cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the declaration of class D.
@@ -3180,7 +3841,7 @@ with compoundStmt()
Matches the condition expression of an if statement, for loop,
 or conditional operator.
 
-Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
@@ -3255,12 +3916,12 @@ declaration's type. In case of a value declaration (for example a variable declaration), this resolves one layer of indirection. For example, in the value -declaration "X x;", recordDecl(hasName("X")) matches the declaration of X, -while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration -of x." +declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of +X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the +declaration of x. -Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) class X {}; void y(X &x) { x; X z; } @@ -3272,8 +3933,8 @@ Usable as: Matcher<
Matches if the expression's or declaration's type matches a type
 matcher.
 
-Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
-            and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
  class X {};
  void y(X &x) { x; X z; }
 
@@ -3361,7 +4022,7 @@ with compoundStmt()
Matches the condition expression of an if statement, for loop,
 or conditional operator.
 
-Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
@@ -3393,7 +4054,7 @@ Does not match the 'this' parameter of a method. Given class X { void f(int x, int y, int z) {} }; -methodDecl(hasAnyParameter(hasName("y"))) +cxxMethodDecl(hasAnyParameter(hasName("y"))) matches f(int x, int y, int z) {} with hasAnyParameter(...) matching int y @@ -3405,7 +4066,7 @@ with hasAnyParameter(...) Given class X { void f(int x) {} }; -methodDecl(hasParameter(0, hasType(varDecl()))) +cxxMethodDecl(hasParameter(0, hasType(varDecl()))) matches f(int x) {} with hasParameter(...) matching int x @@ -3417,7 +4078,7 @@ with hasParameter(...) Given: class X { int f() { return 1; } }; -methodDecl(returns(asString("int"))) +cxxMethodDecl(returns(asString("int"))) matches int f() { return 1; }
@@ -3426,7 +4087,7 @@ methodDecl(returns(asString("int")))
Matches the condition expression of an if statement, for loop,
 or conditional operator.
 
-Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
@@ -3445,7 +4106,7 @@ hasConditionVariableStatement(...)
Matches the else-statement of an if statement.
 
 Examples matches the if statement
-  (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+  (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true)))))
   if (false) false; else true;
 
@@ -3454,7 +4115,7 @@ Examples matches the if statement
Matches the then-statement of an if statement.
 
 Examples matches the if statement
-  (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+  (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true)))))
   if (false) true; else false;
 
@@ -3540,7 +4201,7 @@ matched by a given matcher. Given struct X { int m; }; void f(X x) { x.m; m; } -memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))) +memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))))) matches "x.m" and "m" with hasObjectExpression(...) matching "x" and the implicit object expression of "m" which has type X*. @@ -3612,7 +4273,7 @@ Given struct A { struct B { struct C {}; }; }; A::B::C c; nestedNameSpecifierLoc(specifiesTypeLoc(loc(type( - hasDeclaration(recordDecl(hasName("A"))))))) + hasDeclaration(cxxRecordDecl(hasName("A"))))))) matches "A::"
@@ -3647,11 +4308,35 @@ given QualType matcher without qualifiers. Given struct A { struct B { struct C {}; }; }; A::B::C c; -nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A"))))) +nestedNameSpecifier(specifiesType( + hasDeclaration(cxxRecordDecl(hasName("A"))) +)) matches "A::"
+Matcher<ObjCMessageExpr>hasArgumentunsigned N, Matcher<Expr> InnerMatcher +
Matches the n'th argument of a call expression or a constructor
+call expression.
+
+Example matches y in x(y)
+    (matcher = callExpr(hasArgument(0, declRefExpr())))
+  void x(int) { int y; x(y); }
+
+ + +Matcher<ObjCMessageExpr>hasReceiverTypeMatcher<QualType> InnerMatcher +
Matches on the receiver of an ObjectiveC Message expression.
+
+Example
+matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
+matches the [webView ...] message invocation.
+  NSString *webViewJavaScript = ...
+  UIWebView *webView = ...
+  [webView stringByEvaluatingJavaScriptFromString:webViewJavascript];
+
+ + Matcher<ParenType>innerTypeMatcher<Type>
Matches ParenType nodes where the inner type is a specific type.
 
@@ -3743,7 +4428,8 @@ Usable as: Matcher<
@@ -3759,7 +4445,7 @@ Example matches y->x()
 type matches the specified matcher.
 
 Example matches X &x and const X &y
-    (matcher = varDecl(hasType(references(recordDecl(hasName("X"))))))
+    (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X"))))))
   class X {
     void a(X b) {
       X &x = b;
@@ -4004,7 +4690,8 @@ Generates results for each match.
 For example, in:
   class A { class B {}; class C {}; };
 The matcher:
-  recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m")))
+  cxxRecordDecl(hasName("::A"),
+                findAll(cxxRecordDecl(isDefinition()).bind("m")))
 will generate results for A, B and C.
 
 Usable as: Any Matcher
@@ -4046,7 +4733,8 @@ unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
 Matcher<UnaryOperator>hasUnaryOperandMatcher<Expr> InnerMatcher
 
Matches if the operand of a unary operator matches.
 
-Example matches true (matcher = hasUnaryOperand(boolLiteral(equals(true))))
+Example matches true (matcher = hasUnaryOperand(
+                                  cxxBoolLiteral(equals(true))))
   !true
 
@@ -4101,12 +4789,12 @@ declaration's type. In case of a value declaration (for example a variable declaration), this resolves one layer of indirection. For example, in the value -declaration "X x;", recordDecl(hasName("X")) matches the declaration of X, -while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration -of x." +declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of +X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the +declaration of x. -Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) class X {}; void y(X &x) { x; X z; } @@ -4118,8 +4806,8 @@ Usable as: Matcher<
Matches if the expression's or declaration's type matches a type
 matcher.
 
-Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
-            and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
  class X {};
  void y(X &x) { x; X z; }
 
@@ -4166,7 +4854,7 @@ with compoundStmt()
Matches the condition expression of an if statement, for loop,
 or conditional operator.
 
-Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
 
diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst index fe36511a0cf5..603b2faf01da 100644 --- a/docs/LibASTMatchersTutorial.rst +++ b/docs/LibASTMatchersTutorial.rst @@ -108,7 +108,6 @@ CMakeLists.txt should have the following contents: :: set(LLVM_LINK_COMPONENTS support) - set(LLVM_USED_LIBS clangTooling clangBasic clangAST) add_clang_executable(loop-convert LoopConvert.cpp diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst index 007e0866dec6..62cacce215d0 100644 --- a/docs/MemorySanitizer.rst +++ b/docs/MemorySanitizer.rst @@ -48,10 +48,7 @@ to disable inlining (just use ``-O1``) and tail call elimination % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc If a bug is detected, the program will print an error message to -stderr and exit with a non-zero exit code. Currently, MemorySanitizer -does not symbolize its output by default, so you may need to use a -separate script to symbolize the result offline (this will be fixed in -future). +stderr and exit with a non-zero exit code. .. code-block:: console @@ -60,7 +57,9 @@ future). #0 0x7f45944b418a in main umr.cc:6 #1 0x7f45938b676c in __libc_start_main libc-start.c:226 -By default, MemorySanitizer exits on the first detected error. +By default, MemorySanitizer exits on the first detected error. If you +find the error report hard to understand, try enabling +:ref:`origin tracking `. ``__has_feature(memory_sanitizer)`` ------------------------------------ @@ -80,14 +79,11 @@ whether MemorySanitizer is enabled. :ref:`\_\_has\_feature ``__attribute__((no_sanitize_memory))`` ----------------------------------------------- -Some code should not be checked by MemorySanitizer. -One may use the function attribute -:ref:`no_sanitize_memory ` -to disable uninitialized checks in a particular function. -MemorySanitizer may still instrument such functions to avoid false positives. -This attribute may not be -supported by other compilers, so we suggest to use it together with -``__has_feature(memory_sanitizer)``. +Some code should not be checked by MemorySanitizer. One may use the function +attribute `no_sanitize_memory` to disable uninitialized checks in a particular +function. MemorySanitizer may still instrument such functions to avoid false +positives. This attribute may not be supported by other compilers, so we +suggest to use it together with ``__has_feature(memory_sanitizer)``. Blacklist --------- @@ -105,10 +101,12 @@ MemorySanitizer uses an external symbolizer to print files and line numbers in reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``, or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it. +.. _msan-origins: + Origin Tracking =============== -MemorySanitizer can track origins of unitialized values, similar to +MemorySanitizer can track origins of uninitialized values, similar to Valgrind's --track-origins option. This feature is enabled by ``-fsanitize-memory-track-origins=2`` (or simply ``-fsanitize-memory-track-origins``) Clang option. With the code from @@ -146,14 +144,29 @@ By default, MemorySanitizer collects both allocation points and all intermediate stores the uninitialized value went through. Origin tracking has proved to be very useful for debugging MemorySanitizer reports. It slows down program execution by a factor of 1.5x-2x on top -of the usual MemorySanitizer slowdown. +of the usual MemorySanitizer slowdown and increases memory overhead. -Clang option ``-fsanitize-memory-track-origins=1`` enabled a slightly +Clang option ``-fsanitize-memory-track-origins=1`` enables a slightly faster mode when MemorySanitizer collects only allocation points but not intermediate stores. +Use-after-destruction detection +=============================== + +You can enable experimental use-after-destruction detection in MemorySanitizer. +After invocation of the destructor, the object will be considered no longer +readable, and using underlying memory will lead to error reports in runtime. + +This feature is still experimental, in order to enable it at runtime you need +to: + +#. Pass addition Clang option ``-fsanitize-memory-use-after-dtor`` during + compilation. +#. Set environment variable `MSAN_OPTIONS=poison_in_dtor=1` before running + the program. + Handling external code -============================ +====================== MemorySanitizer requires that all program code is instrumented. This also includes any libraries that the program depends on, even libc. @@ -170,9 +183,7 @@ self-built instrumented libc++ (as a replacement for libstdc++). Supported Platforms =================== -MemorySanitizer is supported on - -* Linux x86\_64 (tested on Ubuntu 12.04); +MemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64. Limitations =========== @@ -183,22 +194,19 @@ Limitations address space. This means that tools like ``ulimit`` may not work as usually expected. * Static linking is not supported. -* Non-position-independent executables are not supported. Therefore, the - ``fsanitize=memory`` flag will cause Clang to act as though the ``-fPIE`` - flag had been supplied if compiling without ``-fPIC``, and as though the - ``-pie`` flag had been supplied if linking an executable. -* Depending on the version of Linux kernel, running without ASLR may - be not supported. Note that GDB disables ASLR by default. To debug - instrumented programs, use "set disable-randomization off". +* Older versions of MSan (LLVM 3.7 and older) didn't work with + non-position-independent executables, and could fail on some Linux + kernel versions with disabled ASLR. Refer to documentation for older versions + for more details. Current Status ============== -MemorySanitizer is an experimental tool. It is known to work on large -real-world programs, like Clang/LLVM itself. +MemorySanitizer is known to work on large real-world programs +(like Clang/LLVM itself) that can be recompiled from source, including all +dependent libraries. More Information ================ -`http://code.google.com/p/memory-sanitizer `_ - +``_ diff --git a/docs/Modules.rst b/docs/Modules.rst index 1f3d89897513..0ea3b5bb3776 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -222,7 +222,7 @@ Modules are modeled as if each submodule were a separate translation unit, and a This behavior is currently only approximated when building a module with submodules. Entities within a submodule that has already been built are visible when building later submodules in that module. This can lead to fragile modules that depend on the build order used for the submodules of the module, and should not be relied upon. This behavior is subject to change. -As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match. In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule. +As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match). In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule. .. note:: diff --git a/docs/RAVFrontendAction.rst b/docs/RAVFrontendAction.rst index ec5d5d54ff9b..c37d3c0e812e 100644 --- a/docs/RAVFrontendAction.rst +++ b/docs/RAVFrontendAction.rst @@ -205,10 +205,10 @@ following CMakeLists.txt to link it: :: - set(LLVM_USED_LIBS clangTooling) - add_clang_executable(find-class-decls FindClassDecls.cpp) + target_link_libraries(find-class-decls clangTooling) + When running this tool over a small code snippet it will output all declarations of a class n::m::C it found: diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 2941afd48fcd..779d45c2928b 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -======================= -Clang 3.7 Release Notes -======================= +===================================== +Clang 3.8 (In-Progress) Release Notes +===================================== .. contents:: :local: @@ -8,12 +8,17 @@ Clang 3.7 Release Notes Written by the `LLVM Team `_ +.. warning:: + + These are in-progress notes for the upcoming Clang 3.8 release. You may + prefer the `Clang 3.7 Release Notes + `_. Introduction ============ This document contains the release notes for the Clang C/C++/Objective-C -frontend, part of the LLVM Compiler Infrastructure, release 3.7. Here we +frontend, part of the LLVM Compiler Infrastructure, release 3.8. Here we describe the status of Clang in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM @@ -26,7 +31,12 @@ the latest release, please check out the main please see the `Clang Web Site `_ or the `LLVM Web Site `_. -What's New in Clang 3.7? +Note that if you are reading this file from a Subversion checkout or the +main Clang web page, this document applies to the *next* release, not +the current one. To see the release notes for a specific release, please +see the `releases page `_. + +What's New in Clang 3.8? ======================== Some of the major new features and improvements to Clang are listed @@ -37,223 +47,147 @@ sections with improvements to Clang's support for those languages. Major New Features ------------------ -- Use of the ``__declspec`` language extension for declaration attributes now - requires passing the -fms-extensions or -fborland compiler flag. This language - extension is also enabled when compiling CUDA code, but its use should be - viewed as an implementation detail that is subject to change. - -- On Windows targets, some uses of the ``__try``, ``__except``, and - ``__finally`` language constructs are supported in Clang 3.7. MSVC-compatible - C++ exceptions are not yet supported, however. - -- Clang 3.7 fully supports OpenMP 3.1 and reported to work on many platforms, - including x86, x86-64 and Power. Also, pragma ``omp simd`` from OpenMP 4.0 is - supported as well. See below for details. - -- Clang 3.7 includes an implementation of :doc:`control flow integrity - `, a security hardening mechanism. - +- Feature1... 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.6 release include: +about them. The improvements since the 3.7 release include: -- -Wrange-loop-analysis analyzes the loop variable type and the container type - to determine whether copies are made of the container elements. If possible, - suggest a const reference type to prevent copies, or a non-reference type - to indicate a copy is made. - -- -Wredundant-move warns when a parameter variable is moved on return and the - return type is the same as the variable. Returning the variable directly - will already make a move, so the call is not needed. - -- -Wpessimizing-move warns when a local variable is moved on return and the - return type is the same as the variable. Copy elision cannot take place with - a move, but can take place if the variable is returned directly. - -- -Wmove is a new warning group which has the previous two warnings, - -Wredundant-move and -Wpessimizing-move, as well as previous warning - -Wself-move. In addition, this group is part of -Wmost and -Wall now. - -- -Winfinite-recursion, a warning for functions that only call themselves, - is now part of -Wmost and -Wall. - -- -Wobjc-circular-container prevents creation of circular containers, - it covers ``NSMutableArray``, ``NSMutableSet``, ``NSMutableDictionary``, - ``NSMutableOrderedSet`` and all their subclasses. +- ... New Compiler Flags ------------------ -The sized deallocation feature of C++14 is now controlled by the -``-fsized-deallocation`` flag. This feature relies on library support that -isn't yet widely deployed, so the user must supply an extra flag to get the -extra functionality. +The option .... +New Pragmas in Clang +----------------------- + +Clang now supports the ... + +Windows Support +--------------- + +Clang's support for building native Windows programs ... + + +C Language Changes in Clang +--------------------------- + +... + +C11 Feature Support +^^^^^^^^^^^^^^^^^^^ + +... + +C++ Language Changes in Clang +----------------------------- + +- ... + +C++11 Feature Support +^^^^^^^^^^^^^^^^^^^^^ + +... + Objective-C Language Changes in Clang ------------------------------------- -- ``objc_boxable`` attribute was added. Structs and unions marked with this attribute can be - used with boxed expressions (``@(...)``) to create ``NSValue``. +... -Profile Guided Optimization ---------------------------- +OpenCL C Language Changes in Clang +---------------------------------- -Clang now accepts GCC-compatible flags for profile guided optimization (PGO). -You can now use ``-fprofile-generate=``, ``-fprofile-use=``, -``-fno-profile-generate`` and ``-fno-profile-use``. These flags have the -same semantics as their GCC counterparts. However, the generated profile -is still LLVM-specific. PGO profiles generated with Clang cannot be used -by GCC and vice-versa. - -Clang now emits function entry counts in profile-instrumented binaries. -This has improved the computation of weights and frequencies in -profile analysis. - -OpenMP Support --------------- -OpenMP 3.1 is fully supported, but disabled by default. To enable it, please use -the ``-fopenmp=libomp`` command line option. Your feedback (positive or negative) on -using OpenMP-enabled clang would be much appreciated; please share it either on -`cfe-dev `_ or `openmp-dev -`_ mailing lists. - -In addition to OpenMP 3.1, several important elements of the 4.0 version of the -standard are supported as well: - -- ``omp simd``, ``omp for simd`` and ``omp parallel for simd`` pragmas -- atomic constructs -- ``proc_bind`` clause of ``omp parallel`` pragma -- ``depend`` clause of ``omp task`` pragma (except for array sections) -- ``omp cancel`` and ``omp cancellation point`` pragmas -- ``omp taskgroup`` pragma +... Internal API Changes -------------------- -These are major API changes that have happened since the 3.6 release of +These are major API changes that have happened since the 3.7 release of Clang. If upgrading an external codebase that uses Clang as a library, this section should help get you past the largest hurdles of upgrading. -- Some of the ``PPCallbacks`` interface now deals in ``MacroDefinition`` - objects instead of ``MacroDirective`` objects. This allows preserving - full information on macros imported from modules. +- ... -- ``clang-c/Index.h`` no longer ``#include``\s ``clang-c/Documentation.h``. - You now need to explicitly ``#include "clang-c/Documentation.h"`` if - you use the libclang documentation API. +AST Matchers +------------ +The AST matcher functions were renamed to reflect the exact AST node names, +which is a breaking change to AST matching code. The following matchers were +affected: + +======================= ============================ +Previous Matcher Name New Matcher Name +======================= ============================ +recordDecl recordDecl and cxxRecordDecl +ctorInitializer cxxCtorInitializer +constructorDecl cxxConstructorDecl +destructorDecl cxxDestructorDecl +methodDecl cxxMethodDecl +conversionDecl cxxConversionDecl +memberCallExpr cxxMemberCallExpr +constructExpr cxxConstructExpr +unresolvedConstructExpr cxxUnresolvedConstructExpr +thisExpr cxxThisExpr +bindTemporaryExpr cxxBindTemporaryExpr +newExpr cxxNewExpr +deleteExpr cxxDeleteExpr +defaultArgExpr cxxDefaultArgExpr +operatorCallExpr cxxOperatorCallExpr +forRangeStmt cxxForRangeStmt +catchStmt cxxCatchStmt +tryStmt cxxTryStmt +throwExpr cxxThrowExpr +boolLiteral cxxBoolLiteral +nullPtrLiteralExpr cxxNullPtrLiteralExpr +reinterpretCastExpr cxxReinterpretCastExpr +staticCastExpr cxxStaticCastExpr +dynamicCastExpr cxxDynamicCastExpr +constCastExpr cxxConstCastExpr +functionalCastExpr cxxFunctionalCastExpr +temporaryObjectExpr cxxTemporaryObjectExpr +CUDAKernalCallExpr cudaKernelCallExpr +======================= ============================ + +recordDecl() previously matched AST nodes of type CXXRecordDecl, but now +matches AST nodes of type RecordDecl. If a CXXRecordDecl is required, use the +cxxRecordDecl() matcher instead. + +... + +libclang +-------- + +... Static Analyzer --------------- -* The generated plists now contain the name of the check that generated it. +... -* Configuration options can now be passed to the checkers (not just the static - analyzer core). +Core Analysis Improvements +========================== -* New check for dereferencing object that the result of a zero-length - allocation. +- ... -* Also check functions in precompiled headers. +New Issues Found +================ -* Properly handle alloca() in some checkers. +- ... -* Various improvements to the retain count checker. +Python Binding Changes +---------------------- +The following methods have been added: -clang-tidy ----------- -Added new checks: +- ... -* google-global-names-in-headers: flag global namespace pollution in header - files. - -* misc-assert-side-effect: detects ``assert()`` conditions with side effects - which can cause different behavior in debug / release builds. - -* misc-assign-operator-signature: finds declarations of assign operators with - the wrong return and/or argument types. - -* misc-inaccurate-erase: warns when some elements of a container are not - removed due to using the ``erase()`` algorithm incorrectly. - -* misc-inefficient-algorithm: warns on inefficient use of STL algorithms on - associative containers. - -* misc-macro-parentheses: finds macros that can have unexpected behavior due - to missing parentheses. - -* misc-macro-repeated-side-effects: checks for repeated argument with side - effects in macros. - -* misc-noexcept-move-constructor: flags user-defined move constructors and - assignment operators not marked with ``noexcept`` or marked with - ``noexcept(expr)`` where ``expr`` evaluates to ``false`` (but is not a - ``false`` literal itself). - -* misc-static-assert: replaces ``assert()`` with ``static_assert()`` if the - condition is evaluable at compile time. - -* readability-container-size-empty: checks whether a call to the ``size()`` - method can be replaced with a call to ``empty()``. - -* readability-else-after-return: flags conditional statements having the - ``else`` branch, when the ``true`` branch has a ``return`` as the last statement. - -* readability-redundant-string-cstr: finds unnecessary calls to - ``std::string::c_str()``. - -* readability-shrink-to-fit: replaces copy and swap tricks on shrinkable - containers with the ``shrink_to_fit()`` method call. - -* readability-simplify-boolean-expr: looks for boolean expressions involving - boolean constants and simplifies them to use the appropriate boolean - expression directly (``if (x == true) ... -> if (x)``, etc.) - -SystemZ -------- - -* Clang will now always default to the z10 processor when compiling - without any ``-march=`` option. Previous releases used to automatically - detect the current host CPU when compiling natively. If you wish to - still have clang detect the current host CPU, you now need to use the - ``-march=native`` option. - -* Clang now provides the ```` header file. - -* Clang now supports the transactional-execution facility and - provides associated builtins and the ```` and - ```` header files. Support is enabled by default - on zEC12 and above, and can additionally be enabled or disabled - via the ``-mhtm`` / ``-mno-htm`` command line options. - -* Clang now supports the vector facility. This includes a - change in the ABI to pass arguments and return values of - vector types in vector registers, as well as a change in - the default alignment of vector types. Support is enabled - by default on z13 and above, and can additionally be enabled - or disabled via the ``-mvx`` / ``-mno-vx`` command line options. - -* Clang now supports the System z vector language extension, - providing a "vector" keyword to define vector types, and a - set of builtins defined in the ```` header file. - This can be enabled via the ``-fzvector`` command line option. - For compatibility with GCC, Clang also supports the - ``-mzvector`` option as an alias. - -* Several cases of ABI incompatibility with GCC have been fixed. - - -Last release which will run on Windows XP and Windows Vista ------------------------------------------------------------ - -This is expected to the be the last major release of Clang that will support -running on Windows XP and Windows Vista. For the next major release the -minimum Windows version requirement will be Windows 7. +Significant Known Problems +========================== Additional Information ====================== diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst index 65af6ffbf010..e759b351c1b5 100644 --- a/docs/SanitizerCoverage.rst +++ b/docs/SanitizerCoverage.rst @@ -249,6 +249,41 @@ These counters may also be used for in-process coverage-guided fuzzers. See uintptr_t __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset); +Tracing basic blocks +==================== +An *experimental* feature to support 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]``). + +Tracing data flow +================= + +An *experimental* feature to support data-flow-guided fuzzing. +With ``-fsanitize-coverage=trace-cmp`` the compiler will insert extra instrumentation +around comparison instructions and switch statements. +The fuzzer will need to define the following functions, +they will be called by the instrumented code. + +.. code-block:: c++ + + // Called before a comparison instruction. + // SizeAndType is a packed value containing + // - [63:32] the Size of the operands of comparison in bits + // - [31:0] the Type of comparison (one of ICMP_EQ, ... ICMP_SLE) + // Arg1 and Arg2 are arguments of the comparison. + void __sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1, uint64_t Arg2); + + // Called before a switch statement. + // Val is the switch operand. + // Cases[0] is the number of case constants. + // Cases[1] is the size of Val in bits. + // Cases[2:] are the case constants. + void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases); + +This interface is a subject to change. +The current implementation is not thread-safe and thus can be safely used only for single-threaded targets. + Output directory ================ diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst index d1aeaa8a58c3..0b9b163a9651 100644 --- a/docs/ThreadSanitizer.rst +++ b/docs/ThreadSanitizer.rst @@ -86,25 +86,22 @@ this purpose. ``__attribute__((no_sanitize_thread))`` ----------------------------------------------- -Some code should not be instrumented by ThreadSanitizer. -One may use the function attribute -:ref:`no_sanitize_thread ` -to disable instrumentation of plain (non-atomic) loads/stores in a particular function. -ThreadSanitizer still instruments such functions to avoid false positives and -provide meaningful stack traces. -This attribute may not be -supported by other compilers, so we suggest to use it together with -``__has_feature(thread_sanitizer)``. +Some code should not be instrumented by ThreadSanitizer. One may use the +function attribute `no_sanitize_thread` to disable instrumentation of plain +(non-atomic) loads/stores in a particular function. ThreadSanitizer still +instruments such functions to avoid false positives and provide meaningful stack +traces. This attribute may not be supported by other compilers, so we suggest +to use it together with ``__has_feature(thread_sanitizer)``. Blacklist --------- ThreadSanitizer supports ``src`` and ``fun`` entity types in -:doc:`SanitizerSpecialCaseList`, that can be used to suppress data race reports in -the specified source files or functions. Unlike functions marked with -:ref:`no_sanitize_thread ` attribute, -blacklisted functions are not instrumented at all. This can lead to false positives -due to missed synchronization via atomic operations and missed stack frames in reports. +:doc:`SanitizerSpecialCaseList`, that can be used to suppress data race reports +in the specified source files or functions. Unlike functions marked with +`no_sanitize_thread` attribute, blacklisted functions are not instrumented at +all. This can lead to false positives due to missed synchronization via atomic +operations and missed stack frames in reports. Limitations ----------- @@ -134,5 +131,4 @@ especially in the form of minimized standalone tests is more than welcome. More Information ---------------- -`http://code.google.com/p/thread-sanitizer `_. - +``_ diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst new file mode 100644 index 000000000000..37ff16d9a9e9 --- /dev/null +++ b/docs/UndefinedBehaviorSanitizer.rst @@ -0,0 +1,204 @@ +========================== +UndefinedBehaviorSanitizer +========================== + +.. contents:: + :local: + +Introduction +============ + +UndefinedBehaviorSanitizer (UBSan) is a fast undefined behavior detector. +UBSan modifies the program at compile-time to catch various kinds of undefined +behavior during program execution, for example: + +* Using misaligned or null pointer +* Signed integer overflow +* Conversion to, from, or between floating-point types which would + overflow the destination + +See the full list of available :ref:`checks ` below. + +UBSan has an optional run-time library which provides better error reporting. +The checks have small runtime cost and no impact on address space layout or ABI. + +How to build +============ + +Build LLVM/Clang with `CMake `_. + +Usage +===== + +Use ``clang++`` to compile and link your program with ``-fsanitize=undefined`` +flag. Make sure to use ``clang++`` (not ``ld``) as a linker, so that your +executable is linked with proper UBSan runtime libraries. You can use ``clang`` +instead of ``clang++`` if you're compiling/linking C code. + +.. code-block:: console + + % cat test.cc + int main(int argc, char **argv) { + int k = 0x7fffffff; + k += argc; + return 0; + } + % clang++ -fsanitize=undefined test.cc + % ./a.out + test.cc:3:5: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' + +You can enable only a subset of :ref:`checks ` offered by UBSan, +and define the desired behavior for each kind of check: + +* print a verbose error report and continue execution (default); +* print a verbose error report and exit the program; +* execute a trap instruction (doesn't require UBSan run-time support). + +For example if you compile/link your program as: + +.. code-block:: console + + % clang++ -fsanitize=signed-integer-overflow,null,alignment -fno-sanitize-recover=null -fsanitize-trap=alignment + +the program will continue execution after signed integer overflows, exit after +the first invalid use of a null pointer, and trap after the first use of misaligned +pointer. + +.. _ubsan-checks: + +Availablle checks +================= + +Available checks are: + + - ``-fsanitize=alignment``: Use of a misaligned pointer or creation + of a misaligned reference. + - ``-fsanitize=bool``: Load of a ``bool`` value which is neither + ``true`` nor ``false``. + - ``-fsanitize=bounds``: Out of bounds array indexing, in cases + where the array bound can be statically determined. + - ``-fsanitize=enum``: Load of a value of an enumerated type which + is not in the range of representable values for that enumerated + type. + - ``-fsanitize=float-cast-overflow``: Conversion to, from, or + between floating-point types which would overflow the + destination. + - ``-fsanitize=float-divide-by-zero``: Floating point division by + zero. + - ``-fsanitize=function``: Indirect call of a function through a + function pointer of the wrong type (Linux, C++ and x86/x86_64 only). + - ``-fsanitize=integer-divide-by-zero``: Integer division by zero. + - ``-fsanitize=nonnull-attribute``: Passing null pointer as a function + 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=return``: In C++, reaching the end of a + value-returning function without returning a value. + - ``-fsanitize=returns-nonnull-attribute``: Returning null pointer + from a function which is declared to never return null. + - ``-fsanitize=shift``: Shift operators where the amount shifted is + greater or equal to the promoted bit-width of the left hand side + or less than zero, or where the left hand side is negative. For a + signed left shift, also checks for signed overflow in C, and for + unsigned overflow in C++. You can use ``-fsanitize=shift-base`` or + ``-fsanitize=shift-exponent`` to check only left-hand side or + right-hand side of shift operation, respectively. + - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, + including all the checks added by ``-ftrapv``, and checking for + overflow in signed division (``INT_MIN / -1``). + - ``-fsanitize=unreachable``: If control flow reaches + ``__builtin_unreachable``. + - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer + overflows. + - ``-fsanitize=vla-bound``: A variable-length array whose bound + does not evaluate to a positive value. + - ``-fsanitize=vptr``: Use of an object whose vptr indicates that + it is of the wrong dynamic type, or that its lifetime has not + begun or has ended. Incompatible with ``-fno-rtti``. Link must + be performed by ``clang++``, not ``clang``, to make sure C++-specific + parts of the runtime library and C++ standard libraries are present. + +You can also use the following check groups: + - ``-fsanitize=undefined``: All of the checks listed above other than + ``unsigned-integer-overflow``. + - ``-fsanitize=undefined-trap``: Deprecated alias of + ``-fsanitize=undefined``. + - ``-fsanitize=integer``: Checks for undefined or suspicious integer + behavior (e.g. unsigned integer overflow). + +Stack traces and report symbolization +===================================== +If you want UBSan to print symbolized stack trace for each error report, you +will need to: + +#. Compile with ``-g`` and ``-fno-omit-frame-pointer`` to get proper debug + information in your binary. +#. Run your program with environment variable + ``UBSAN_OPTIONS=print_stacktrace=1``. +#. Make sure ``llvm-symbolizer`` binary is in ``PATH``. + +Issue Suppression +================= + +UndefinedBehaviorSanitizer is not expected to produce false positives. +If you see one, look again; most likely it is a true positive! + +Disabling Instrumentation with ``__attribute__((no_sanitize("undefined")))`` +---------------------------------------------------------------------------- + +You disable UBSan checks for particular functions with +``__attribute__((no_sanitize("undefined")))``. You can use all values of +``-fsanitize=`` flag in this attribute, e.g. if your function deliberately +contains possible signed integer overflow, you can use +``__attribute__((no_sanitize("signed-integer-overflow")))``. + +This attribute may not be +supported by other compilers, so consider using it together with +``#if defined(__clang__)``. + +Suppressing Errors in Recompiled Code (Blacklist) +------------------------------------------------- + +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. + +Supported Platforms +=================== + +UndefinedBehaviorSanitizer is supported on the following OS: + +* Android +* Linux +* FreeBSD +* OS X 10.6 onwards + +and for the following architectures: + +* i386/x86\_64 +* ARM +* AArch64 +* PowerPC64 +* MIPS/MIPS64 + +Current Status +============== + +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. + +More Information +================ + +* From LLVM project blog: + `What Every C Programmer Should Know About Undefined Behavior + `_ +* From John Regehr's *Embedded in Academia* blog: + `A Guide to Undefined Behavior in C and C++ + `_ diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index 78d8dcc11a9f..5fe1e371df64 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -148,8 +148,8 @@ Formatting of Diagnostics Clang aims to produce beautiful diagnostics by default, particularly for new users that first come to Clang. However, different people have -different preferences, and sometimes Clang is driven by another program -that wants to parse simple and consistent output, not a person. For +different preferences, and sometimes Clang is driven not by a human, +but by a program that wants consistent and easily parsable output. For these cases, Clang provides a wide range of options to control the exact output format of the diagnostics that it generates. @@ -952,26 +952,18 @@ are listed below. ``-fsanitize=address``: :doc:`AddressSanitizer`, a memory error detector. - - ``-fsanitize=integer``: Enables checks for undefined or - suspicious integer behavior. - .. _opt_fsanitize_thread: ``-fsanitize=thread``: :doc:`ThreadSanitizer`, a data race detector. - .. _opt_fsanitize_memory: ``-fsanitize=memory``: :doc:`MemorySanitizer`, - an *experimental* detector of uninitialized reads. Not ready for - widespread use. + a detector of uninitialized reads. Requires instrumentation of all + program code. - .. _opt_fsanitize_undefined: - ``-fsanitize=undefined``: Fast and compatible undefined behavior - checker. Enables the undefined behavior checks that have small - runtime cost and no impact on address space layout or ABI. This - includes all of the checks listed below other than - ``unsigned-integer-overflow``. - - - ``-fsanitize=undefined-trap``: This is a deprecated alias for - ``-fsanitize=undefined``. + ``-fsanitize=undefined``: :doc:`UndefinedBehaviorSanitizer`, + a fast and compatible undefined behavior checker. - ``-fsanitize=dataflow``: :doc:`DataFlowSanitizer`, a general data flow analysis. @@ -980,103 +972,17 @@ are listed below. - ``-fsanitize=safe-stack``: :doc:`safe stack ` protection against stack-based memory corruption errors. - The following more fine-grained checks are also available: - - - ``-fsanitize=alignment``: Use of a misaligned pointer or creation - of a misaligned reference. - - ``-fsanitize=bool``: Load of a ``bool`` value which is neither - ``true`` nor ``false``. - - ``-fsanitize=bounds``: Out of bounds array indexing, in cases - where the array bound can be statically determined. - - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks - `. - - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong - dynamic type. Requires ``-flto``. - - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another - unrelated type to the wrong dynamic type. Requires ``-flto``. - - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of - the wrong dynamic type. Requires ``-flto``. - - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the - wrong dynamic type. Requires ``-flto``. - - ``-fsanitize=enum``: Load of a value of an enumerated type which - is not in the range of representable values for that enumerated - type. - - ``-fsanitize=float-cast-overflow``: Conversion to, from, or - between floating-point types which would overflow the - destination. - - ``-fsanitize=float-divide-by-zero``: Floating point division by - zero. - - ``-fsanitize=function``: Indirect call of a function through a - function pointer of the wrong type (Linux, C++ and x86/x86_64 only). - - ``-fsanitize=integer-divide-by-zero``: Integer division by zero. - - ``-fsanitize=nonnull-attribute``: Passing null pointer as a function - 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=return``: In C++, reaching the end of a - value-returning function without returning a value. - - ``-fsanitize=returns-nonnull-attribute``: Returning null pointer - from a function which is declared to never return null. - - ``-fsanitize=shift``: Shift operators where the amount shifted is - greater or equal to the promoted bit-width of the left hand side - or less than zero, or where the left hand side is negative. For a - signed left shift, also checks for signed overflow in C, and for - unsigned overflow in C++. You can use ``-fsanitize=shift-base`` or - ``-fsanitize=shift-exponent`` to check only left-hand side or - right-hand side of shift operation, respectively. - - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, - including all the checks added by ``-ftrapv``, and checking for - overflow in signed division (``INT_MIN / -1``). - - ``-fsanitize=unreachable``: If control flow reaches - ``__builtin_unreachable``. - - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer - overflows. - - ``-fsanitize=vla-bound``: A variable-length array whose bound - does not evaluate to a positive value. - - ``-fsanitize=vptr``: Use of an object whose vptr indicates that - it is of the wrong dynamic type, or that its lifetime has not - begun or has ended. Incompatible with ``-fno-rtti``. - - You can turn off or modify checks for certain source files, functions - or even variables by providing a special file: - - - ``-fsanitize-blacklist=/path/to/blacklist/file``: disable or modify - sanitizer checks for objects listed in the file. See - :doc:`SanitizerSpecialCaseList` for file format description. - - ``-fno-sanitize-blacklist``: don't use blacklist file, if it was - specified earlier in the command line. - - Extra features of MemorySanitizer (require explicit - ``-fsanitize=memory``): - - - ``-fsanitize-memory-track-origins[=level]``: Enables origin tracking in - MemorySanitizer. Adds a second section to MemorySanitizer - reports pointing to the heap or stack allocation the - uninitialized bits came from. Slows down execution by additional - 1.5x-2x. - - Possible values for level are 0 (off), 1, 2 (default). Level 2 - adds more sections to MemorySanitizer reports describing the - order of memory stores the uninitialized value went - through. This mode may use extra memory in programs that copy - uninitialized memory a lot. + There are more fine-grained checks available: see + the :ref:`list ` of specific kinds of + undefined behavior that can be detected and the :ref:`list ` + of control flow integrity schemes. The ``-fsanitize=`` argument must also be provided when linking, in - order to link to the appropriate runtime library. When using - ``-fsanitize=vptr`` (or a group that includes it, such as - ``-fsanitize=undefined``) with a C++ program, the link must be - performed by ``clang++``, not ``clang``, in order to link against the - C++-specific parts of the runtime library. + order to link to the appropriate runtime library. It is not possible to combine more than one of the ``-fsanitize=address``, ``-fsanitize=thread``, and ``-fsanitize=memory`` checkers in the same - program. The ``-fsanitize=undefined`` checks can only be combined with - ``-fsanitize=address``. + program. **-f[no-]sanitize-recover=check1,check2,...** @@ -1084,10 +990,12 @@ are listed below. If the check is fatal, program will halt after the first error of this kind is detected and error report is printed. - By default, non-fatal checks are those enabled by UndefinedBehaviorSanitizer, + By default, non-fatal checks are those enabled by + :doc:`UndefinedBehaviorSanitizer`, except for ``-fsanitize=return`` and ``-fsanitize=unreachable``. Some - sanitizers (e.g. :doc:`AddressSanitizer`) may not support recovery, - and always crash the program after the issue is detected. + sanitizers may not support recovery (or not support it by default + e.g. :doc:`AddressSanitizer`), and always crash the program after the issue + is detected. Note that the ``-fsanitize-trap`` flag has precedence over this flag. This means that if a check has been configured to trap elsewhere on the @@ -1107,14 +1015,24 @@ are listed below. be used (for instance, when building libc or a kernel module), or where the binary size increase caused by the sanitizer runtime is a concern. - This flag is only compatible with ``local-bounds``, - ``unsigned-integer-overflow``, sanitizers in the ``cfi`` group and - sanitizers in the ``undefined`` group other than ``vptr``. If this flag + This flag is only compatible with :doc:`control flow integrity + ` schemes and :doc:`UndefinedBehaviorSanitizer` + checks other than ``vptr``. If this flag is supplied together with ``-fsanitize=undefined``, the ``vptr`` sanitizer will be implicitly disabled. This flag is enabled by default for sanitizers in the ``cfi`` group. +.. option:: -fsanitize-blacklist=/path/to/blacklist/file + + Disable or modify sanitizer checks for objects (source files, functions, + variables, types) listed in the file. See + :doc:`SanitizerSpecialCaseList` for file format description. + +.. option:: -fno-sanitize-blacklist + + Don't use blacklist file, if it was specified earlier in the command line. + **-f[no-]sanitize-coverage=[type,features,...]** Enable simple code coverage in addition to certain sanitizers. @@ -1124,6 +1042,12 @@ are listed below. Deprecated alias for ``-fsanitize-trap=undefined``. +.. option:: -fsanitize-cfi-cross-dso + + Enable cross-DSO control flow integrity checks. This flag modifies + the behavior of sanitizers in the ``cfi`` group to allow checking + of cross-DSO virtual and indirect calls. + .. option:: -fno-assume-sane-operator-new Don't assume that the C++'s new operator is sane. @@ -1157,6 +1081,13 @@ are listed below. efficient model can be used. The TLS model can be overridden per variable using the ``tls_model`` attribute. +.. option:: -femulated-tls + + Select emulated TLS model, which overrides all -ftls-model choices. + + In emulated TLS mode, all access to TLS variables are converted to + calls to __emutls_get_address in the runtime library. + .. option:: -mhwdiv=[values] Select the ARM modes (arm or thumb) that support hardware division @@ -1183,7 +1114,7 @@ are listed below. This option restricts the generated code to use general registers only. This only applies to the AArch64 architecture. -**-f[no-]max-unknown-pointer-align=[number]** +**-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. This cap is ignored when directly accessing a variable or when the pointee @@ -1211,7 +1142,7 @@ are listed below. void initialize_vector(__aligned_v16si *v) { // The compiler may assume that ‘v’ is 64-byte aligned, regardless of the - // value of -fmax-unknown-pointer-align. + // value of -fmax-type-align. } @@ -1338,15 +1269,18 @@ read by the backend. LLVM supports three different sample profile formats: 1. ASCII text. This is the easiest one to generate. The file is divided into sections, which correspond to each of the functions with profile - information. The format is described below. + information. The format is described below. It can also be generated from + the binary or gcov formats using the ``llvm-profdata`` tool. 2. Binary encoding. This uses a more efficient encoding that yields smaller - profile files, which may be useful when generating large profiles. It can be - generated from the text format using the ``llvm-profdata`` tool. + profile files. This is the format generated by the ``create_llvm_prof`` tool + in http://github.com/google/autofdo. 3. GCC encoding. This is based on the gcov format, which is accepted by GCC. It - is only interesting in environments where GCC and Clang co-exist. Similarly - to the binary encoding, it can be generated using the ``llvm-profdata`` tool. + is only interesting in environments where GCC and Clang co-exist. This + encoding is only generated by the ``create_gcov`` tool in + http://github.com/google/autofdo. It can be read by LLVM and + ``llvm-profdata``, but it cannot be generated by either. If you are using Linux Perf to generate sampling profiles, you can use the conversion tool ``create_llvm_prof`` described in the previous section. @@ -1360,19 +1294,32 @@ Sample Profile Text Format This section describes the ASCII text format for sampling profiles. It is, arguably, the easiest one to generate. If you are interested in generating any of the other two, consult the ``ProfileData`` library in in LLVM's source tree -(specifically, ``llvm/lib/ProfileData/SampleProfWriter.cpp``). +(specifically, ``include/llvm/ProfileData/SampleProfReader.h``). .. code-block:: console function1:total_samples:total_head_samples - offset1[.discriminator]: number_of_samples [fn1:num fn2:num ... ] - offset2[.discriminator]: number_of_samples [fn3:num fn4:num ... ] - ... - offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ] + offset1[.discriminator]: number_of_samples [fn1:num fn2:num ... ] + offset2[.discriminator]: number_of_samples [fn3:num fn4:num ... ] + ... + offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ] + offsetA[.discriminator]: fnA:num_of_total_samples + offsetA1[.discriminator]: number_of_samples [fn7:num fn8:num ... ] + offsetA1[.discriminator]: number_of_samples [fn9:num fn10:num ... ] + offsetB[.discriminator]: fnB:num_of_total_samples + offsetB1[.discriminator]: number_of_samples [fn11:num fn12:num ... ] -The file may contain blank lines between sections and within a -section. However, the spacing within a single line is fixed. Additional -spaces will result in an error while reading the file. +This is a nested tree in which the identation represents the nesting level +of the inline stack. There are no blank lines in the file. And the spacing +within a single line is fixed. Additional spaces will result in an error +while reading the file. + +Any line starting with the '#' character is completely ignored. + +Inlined calls are represented with indentation. The Inline stack is a +stack of source locations in which the top of the stack represents the +leaf function, and the bottom of the stack represents the actual +symbol to which the instruction belongs. Function names must be mangled in order for the profile loader to match them in the current translation unit. The two numbers in the @@ -1381,6 +1328,14 @@ function (first number), and the total number of samples accumulated in the prologue of the function (second number). This head sample count provides an indicator of how frequently the function is invoked. +There are two types of lines in the function body. + +- Sampled line represents the profile information of a source location. + ``offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ]`` + +- Callsite line represents the profile information of an inlined callsite. + ``offsetA[.discriminator]: fnA:num_of_total_samples`` + Each sampled line may contain several items. Some are optional (marked below): @@ -1434,6 +1389,24 @@ d. [OPTIONAL] Potential call targets and samples. If present, this instruction that calls one of ``foo()``, ``bar()`` and ``baz()``, with ``baz()`` being the relatively more frequently called target. +As an example, consider a program with the call chain ``main -> foo -> bar``. +When built with optimizations enabled, the compiler may inline the +calls to ``bar`` and ``foo`` inside ``main``. The generated profile +could then be something like this: + +.. code-block:: console + + main:35504:0 + 1: _Z3foov:35504 + 2: _Z32bari:31977 + 1.1: 31977 + 2: 0 + +This profile indicates that there were a total of 35,504 samples +collected in main. All of those were at line 1 (the call to ``foo``). +Of those, 31,977 were spent inside the body of ``bar``. The last line +of the profile (``2: 0``) corresponds to line 2 inside ``main``. No +samples were collected there. Profiling with Instrumentation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1527,9 +1500,25 @@ with respect to profile creation and use. profile file, it reads from that file. If ``pathname`` is a directory name, it reads from ``pathname/default.profdata``. +Disabling Instrumentation +^^^^^^^^^^^^^^^^^^^^^^^^^ + +In certain situations, it may be useful to disable profile generation or use +for specific files in a build, without affecting the main compilation flags +used for the other files in the project. + +In these cases, you can use the flag ``-fno-profile-instr-generate`` (or +``-fno-profile-generate``) to disable profile generation, and +``-fno-profile-instr-use`` (or ``-fno-profile-use``) to disable profile use. + +Note that these flags should appear after the corresponding profile +flags to have an effect. + +Controlling Debug Information +----------------------------- Controlling Size of Debug Information -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Debug info kind generated by Clang can be set by one of the flags listed below. If multiple flags are present, the last one is used. @@ -1573,6 +1562,21 @@ below. If multiple flags are present, the last one is used. Generate complete debug info. +Controlling Debugger "Tuning" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +While Clang generally emits standard DWARF debug info (http://dwarfstd.org), +different debuggers may know how to take advantage of different specific DWARF +features. You can "tune" the debug info for one of several different debuggers. + +.. option:: -ggdb, -glldb, -gsce + + Tune the debug info for the ``gdb``, ``lldb``, or Sony Computer Entertainment + debugger, respectively. Each of these options implies **-g**. (Therefore, if + you want both **-gline-tables-only** and debugger tuning, the tuning option + must come first.) + + Comment Parsing Options ----------------------- @@ -1832,6 +1836,32 @@ Objective-C Language Features Objective-C++ Language Features =============================== +.. _openmp: + +OpenMP Features +=============== + +Clang supports all OpenMP 3.1 directives and clauses. In addition, some +features of OpenMP 4.0 are supported. For example, ``#pragma omp simd``, +``#pragma omp for simd``, ``#pragma omp parallel for simd`` directives, extended +set of atomic constructs, ``proc_bind`` clause for all parallel-based +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`. + +Controlling implementation limits +--------------------------------- + +.. option:: -fopenmp-use-tls + + 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` + is provided or target does not support TLS, code generation for threadprivate + variables relies on OpenMP runtime library. .. _target_features: @@ -2019,11 +2049,11 @@ Execute ``clang-cl /?`` to see a list of supported options: /FI Include file before parsing /Fi Set preprocess output file name (with /P) /Fo Set output object file, or directory (ends in / or \) (with /c) - /fp:except- - /fp:except - /fp:fast - /fp:precise - /fp:strict + /fp:except- + /fp:except + /fp:fast + /fp:precise + /fp:strict /GA Assume thread-local variables are defined in the executable /GF- Disable string pooling /GR- Disable emission of RTTI data @@ -2049,10 +2079,9 @@ Execute ``clang-cl /?`` to see a list of supported options: /Oi Enable use of builtin functions /Os Optimize for size /Ot Optimize for speed - /Ox Maximum optimization /Oy- Disable frame pointer omission /Oy Enable frame pointer omission - /O Optimization level + /O Optimization level /o Set output file or directory (ends in / or \) /P Preprocess to file /Qvec- Disable the loop vectorization passes @@ -2075,11 +2104,12 @@ Execute ``clang-cl /?`` to see a list of supported options: /W1 Enable -Wall /W2 Enable -Wall /W3 Enable -Wall - /W4 Enable -Wall + /W4 Enable -Wall and -Wextra /Wall Enable -Wall /WX- Do not treat warnings as errors /WX Treat warnings as errors /w Disable all warnings + /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 /Zc:strictStrings Treat string literals as const @@ -2087,7 +2117,8 @@ 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 - /Zi Enable debug information + /Zi Alias for /Z7. Does not produce PDBs. + /Zl Don't mention any default libraries in the object file /Zp Set the default maximum struct packing alignment to 1 /Zp Specify the default maximum struct packing alignment /Zs Syntax-check only @@ -2119,6 +2150,7 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize-trap= Enable trapping for specified sanitizers -fsanitize= Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks + -gcodeview Generate CodeView debug information -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 14d6ae4c4c91..771e39fc4395 100644 --- a/docs/analyzer/DebugChecks.rst +++ b/docs/analyzer/DebugChecks.rst @@ -138,6 +138,29 @@ ExprInspection checks clang_analyzer_warnIfReached(); // no-warning } +- void clang_analyzer_warnOnDeadSymbol(int); + + Subscribe for a delayed warning when the symbol that represents the value of + the argument is garbage-collected by the analyzer. + + When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a + symbol, then this symbol is marked by the ExprInspection checker. Then, + during each garbage collection run, the checker sees if the marked symbol is + being collected and issues the 'SYMBOL DEAD' warning if it does. + This way you know where exactly, up to the line of code, the symbol dies. + + It is unlikely that you call this function after the symbol is already dead, + because the very reference to it as the function argument prevents it from + dying. However, if the argument is not a symbol but a concrete value, + no warning would be issued. + + Example usage:: + + do { + int x = generate_some_integer(); + clang_analyzer_warnOnDeadSymbol(x); + } while(0); // expected-warning{{SYMBOL DEAD}} + Statistics ========== diff --git a/docs/analyzer/nullability.rst b/docs/analyzer/nullability.rst new file mode 100644 index 000000000000..93909d0f25de --- /dev/null +++ b/docs/analyzer/nullability.rst @@ -0,0 +1,92 @@ +============ +Nullability Checks +============ + +This document is a high level description of the nullablility checks. +These checks intended to use the annotations that is described in this +RFC: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-March/041798.html. + +Let's consider the following 2 categories: + +1) nullable +============ + +If a pointer 'p' has a nullable annotation and no explicit null check or assert, we should warn in the following cases: +- 'p' gets implicitly converted into nonnull pointer, for example, we are passing it to a function that takes a nonnull parameter. +- 'p' gets dereferenced + +Taking a branch on nullable pointers are the same like taking branch on null unspecified pointers. + +Explicit cast from nullable to nonnul:: + + __nullable id foo; + id bar = foo; + takesNonNull((_nonnull) bar); <— should not warn here (backward compatibility hack) + anotherTakesNonNull(bar); <— would be great to warn here, but not necessary(*) + +Because bar corresponds to the same symbol all the time it is not easy to implement the checker that way the cast only suppress the first call but not the second. For this reason in the first implementation after a contradictory cast happens, I will treat bar as nullable unspecified, this way all of the warnings will be suppressed. Treating the symbol as nullable unspecified also has an advantage that in case the takesNonNull function body is being inlined, the will be no warning, when the symbol is dereferenced. In case I have time after the initial version I might spend additional time to try to find a more sophisticated solution, in which we would produce the second warning (*). + +2) nonnull +============ + +- Dereferencing a nonnull, or sending message to it is ok. +- Converting nonnull to nullable is Ok. +- When there is an explicit cast from nonnull to nullable I will trust the cast (it is probable there for a reason, because this cast does not suppress any warnings or errors). +- But what should we do about null checks?:: + + __nonnull id takesNonnull(__nonnull id x) { + if (x == nil) { + // Defensive backward compatible code: + .... + return nil; <- Should the analyzer cover this piece of code? Should we require the cast (__nonnull)nil? + } + .... + } + +There are these directions: +- We can either take the branch; this way the branch is analyzed + - Should we not warn about any nullability issues in that branch? Probably not, it is ok to break the nullability postconditions when the nullability preconditions are violated. +- We can assume that these pointers are not null and we lose coverage with the analyzer. (This can be implemented either in constraint solver or in the checker itself.) + +Other Issues to keep in mind/take care of: +Messaging: +- Sending a message to a nullable pointer + - Even though the method might return a nonnull pointer, when it was sent to a nullable pointer the return type will be nullable. + - The result is nullable unless the receiver is known to be non null. +- Sending a message to a unspecified or nonnull pointer + - If the pointer is not assumed to be nil, we should be optimistic and use the nullability implied by the method. + - This will not happen automatically, since the AST will have null unspecified in this case. + +Inlining +============ + +A symbol may need to be treated differently inside an inlined body. For example, consider these conversions from nonnull to nullable in presence of inlining:: + + id obj = getNonnull(); + takesNullable(obj); + takesNonnull(obj); + + void takesNullable(nullable id obj) { + obj->ivar // we should assume obj is nullable and warn here + } + +With no special treatment, when the takesNullable is inlined the analyzer will not warn when the obj symbol is dereferenced. One solution for this is to reanalyze takesNullable as a top level function to get possible violations. The alternative method, deducing nullability information from the arguments after inlining is not robust enough (for example there might be more parameters with different nullability, but in the given path the two parameters might end up being the same symbol or there can be nested functions that take different view of the nullability of the same symbol). So the symbol will remain nonnull to avoid false positives but the functions that takes nullable parameters will be analyzed separately as well without inlining. + +Annotations on multi level pointers +============ + +Tracking multiple levels of annotations for pointers pointing to pointers would make the checker more complicated, because this way a vector of nullability qualifiers would be needed to be tracked for each symbol. This is not a big caveat, since once the top level pointer is dereferenced, the symvol for the inner pointer will have the nullability information. The lack of multi level annotation tracking only observable, when multiple levels of pointers are passed to a function which has a parameter with multiple levels of annotations. So for now the checker support the top level nullability qualifiers only.:: + + int * __nonnull * __nullable p; + int ** q = p; + takesStarNullableStarNullable(q); + +Implementation notes +============ + +What to track? +- The checker would track memory regions, and to each relevant region a qualifier information would be attached which is either nullable, nonnull or null unspecified (or contradicted to suppress warnings for a specific region). +- On a branch, where a nullable pointer is known to be non null, the checker treat it as a same way as a pointer annotated as nonnull. +- When there is an explicit cast from a null unspecified to either nonnull or nullable I will trust the cast. +- Unannotated pointers are treated the same way as pointers annotated with nullability unspecified qualifier, unless the region is wrapped in ASSUME_NONNULL macros. +- We might want to implement a callback for entry points to top level functions, where the pointer nullability assumptions would be made. diff --git a/docs/conf.py b/docs/conf.py index b7ed23ac66d2..6d53d94aa318 100644 --- a/docs/conf.py +++ b/docs/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' -copyright = u'2007-2015, The Clang Team' +copyright = u'2007-%d, The Clang 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.7' +version = '3.8' # The full version, including alpha/beta/rc tags. -release = '3.7' +release = '3.8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in index b4cfbbdf7f42..f6c7cba6d39a 100644 --- a/docs/doxygen.cfg.in +++ b/docs/doxygen.cfg.in @@ -169,7 +169,7 @@ SHORT_NAMES = NO # description.) # The default value is: NO. -JAVADOC_AUTOBRIEF = NO +JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If @@ -177,7 +177,7 @@ JAVADOC_AUTOBRIEF = NO # requiring an explicit \brief command for a brief description.) # The default value is: NO. -QT_AUTOBRIEF = NO +QT_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as diff --git a/docs/index.rst b/docs/index.rst index d50667d56691..a0a70c0e61e5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,6 +24,7 @@ Using Clang as a Compiler AddressSanitizer ThreadSanitizer MemorySanitizer + UndefinedBehaviorSanitizer DataFlowSanitizer LeakSanitizer SanitizerCoverage diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py index 1e1fd3c9d69d..9ecff049c963 100644 --- a/docs/tools/dump_ast_matchers.py +++ b/docs/tools/dump_ast_matchers.py @@ -166,7 +166,7 @@ def act_on_decl(declaration, comment, allowed_types): \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\) \)\s*;\s*$""", declaration, flags=re.X) if m: - loc, name, n_results, results = m.groups()[0:4] + loc, name, results = m.groups()[0:3] result_types = [r.strip() for r in results.split(',')] comment_result_types = extract_result_types(comment) @@ -191,8 +191,8 @@ def act_on_decl(declaration, comment, allowed_types): \)\s*{\s*$""", declaration, flags=re.X) if m: - p, n, name, n_results, results = m.groups()[0:5] - args = m.groups()[5:] + p, n, name, results = m.groups()[0:4] + args = m.groups()[4:] result_types = [r.strip() for r in results.split(',')] if allowed_types and allowed_types != result_types: raise Exception('Inconsistent documentation for: %s' % name) @@ -364,6 +364,6 @@ def sort_table(matcher_type, matcher_map): reference = re.sub(r'', '%s', reference, flags=re.S) % traversal_matcher_table -with open('../LibASTMatchersReference.html', 'w') as output: +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 fdf03c6244ce..b61d2017d05f 100644 --- a/docs/tools/dump_format_style.py +++ b/docs/tools/dump_format_style.py @@ -36,14 +36,35 @@ def __init__(self, name, type, comment): self.type = type self.comment = comment.strip() self.enum = None + self.nested_struct = None def __str__(self): s = '**%s** (``%s``)\n%s' % (self.name, self.type, doxygen2rst(indent(self.comment, 2))) if self.enum: s += indent('\n\nPossible values:\n\n%s\n' % self.enum, 2) + if self.nested_struct: + s += indent('\n\nNested configuration flags:\n\n%s\n' %self.nested_struct, + 2) return s +class NestedStruct: + def __init__(self, name, comment): + self.name = name + self.comment = comment.strip() + self.values = [] + + def __str__(self): + return '\n'.join(map(str, self.values)) + +class NestedField: + def __init__(self, name, comment): + self.name = name + self.comment = comment.strip() + + def __str__(self): + return '* ``%s`` %s' % (self.name, doxygen2rst(self.comment)) + class Enum: def __init__(self, name, comment): self.name = name @@ -65,18 +86,24 @@ def __str__(self): doxygen2rst(indent(self.comment, 2))) def clean_comment_line(line): - return line[3:].strip() + '\n' + if line == '/// \\code': + return '\n.. code-block:: c++\n\n' + if line == '/// \\endcode': + return '' + return line[4:] + '\n' def read_options(header): class State: - BeforeStruct, Finished, InStruct, InFieldComment, InEnum, \ - InEnumMemberComment = range(6) + BeforeStruct, Finished, InStruct, InNestedStruct, InNestedFieldComent, \ + InFieldComment, InEnum, InEnumMemberComment = range(8) state = State.BeforeStruct options = [] enums = {} + nested_structs = {} comment = '' enum = None + nested_struct = None for line in header: line = line.strip() @@ -97,13 +124,31 @@ class State: state = State.InEnum name = re.sub(r'enum\s+(\w+)\s*\{', '\\1', line) enum = Enum(name, comment) + elif line.startswith('struct'): + state = State.InNestedStruct + name = re.sub(r'struct\s+(\w+)\s*\{', '\\1', line) + nested_struct = NestedStruct(name, comment) elif line.endswith(';'): state = State.InStruct - field_type, field_name = re.match(r'([<>:\w]+)\s+(\w+);', line).groups() + field_type, field_name = re.match(r'([<>:\w(,\s)]+)\s+(\w+);', + line).groups() option = Option(str(field_name), str(field_type), comment) options.append(option) else: raise Exception('Invalid format, expected comment, field or enum') + elif state == State.InNestedStruct: + if line.startswith('///'): + state = State.InNestedFieldComent + comment = clean_comment_line(line) + elif line == '};': + state = State.InStruct + nested_structs[nested_struct.name] = nested_struct + elif state == State.InNestedFieldComent: + if line.startswith('///'): + comment += clean_comment_line(line) + else: + state = State.InNestedStruct + nested_struct.values.append(NestedField(line.replace(';', ''), comment)) elif state == State.InEnum: if line.startswith('///'): state = State.InEnumMemberComment @@ -124,9 +169,12 @@ class State: for option in options: if not option.type in ['bool', 'unsigned', 'int', 'std::string', - 'std::vector']: + 'std::vector', + 'std::vector']: if enums.has_key(option.type): option.enum = enums[option.type] + elif nested_structs.has_key(option.type): + option.nested_struct = nested_structs[option.type]; else: raise Exception('Unknown type: %s' % option.type) return options @@ -140,6 +188,6 @@ class State: contents = substitute(contents, 'FORMAT_STYLE_OPTIONS', options_text) -with open(DOC_FILE, 'w') as output: +with open(DOC_FILE, 'wb') as output: output.write(contents) diff --git a/examples/analyzer-plugin/MainCallChecker.cpp b/examples/analyzer-plugin/MainCallChecker.cpp index a6f69fd175bc..7f08760e3d4c 100644 --- a/examples/analyzer-plugin/MainCallChecker.cpp +++ b/examples/analyzer-plugin/MainCallChecker.cpp @@ -30,7 +30,7 @@ void MainCallChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const return; if (II->isStr("main")) { - ExplodedNode *N = C.generateSink(); + ExplodedNode *N = C.generateErrorNode(); if (!N) return; diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h index 068a677a95ed..9359abfebfe0 100644 --- a/include/clang-c/CXCompilationDatabase.h +++ b/include/clang-c/CXCompilationDatabase.h @@ -125,6 +125,12 @@ clang_CompileCommands_getCommand(CXCompileCommands, unsigned I); CINDEX_LINKAGE CXString clang_CompileCommand_getDirectory(CXCompileCommand); +/** + * \brief Get the filename associated with the CompileCommand. + */ +CINDEX_LINKAGE CXString +clang_CompileCommand_getFilename(CXCompileCommand); + /** * \brief Get the number of arguments in the compiler invocation. * diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h index a649cdf82fc7..68ab7bc5244c 100644 --- a/include/clang-c/CXString.h +++ b/include/clang-c/CXString.h @@ -40,6 +40,11 @@ typedef struct { unsigned private_flags; } CXString; +typedef struct { + CXString *Strings; + unsigned Count; +} CXStringSet; + /** * \brief Retrieve the character data associated with the given string. */ @@ -50,6 +55,11 @@ CINDEX_LINKAGE const char *clang_getCString(CXString string); */ CINDEX_LINKAGE void clang_disposeString(CXString string); +/** + * \brief Free the given string set. + */ +CINDEX_LINKAGE void clang_disposeStringSet(CXStringSet *set); + /** * @} */ diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index fad9cfa61b3c..09e216082630 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 30 +#define CINDEX_VERSION_MINOR 32 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -285,7 +285,6 @@ CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex); */ typedef void *CXFile; - /** * \brief Retrieve the complete file and path name of the given file. */ @@ -705,7 +704,6 @@ CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags); CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags, unsigned Index); - /** * \brief Describes the kind of error that occurred (if any) in a call to * \c clang_loadDiagnostics. @@ -1202,7 +1200,15 @@ enum CXTranslationUnit_Flags { * included into the set of code completions returned from this translation * unit. */ - CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80 + CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80, + + /** + * \brief Used to indicate that the precompiled preamble should be created on + * the first parse. Otherwise it will be created on the first reparse. This + * 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 }; /** @@ -1288,6 +1294,17 @@ clang_parseTranslationUnit2(CXIndex CIdx, unsigned options, CXTranslationUnit *out_TU); +/** + * \brief Same as clang_parseTranslationUnit2 but requires a full command line + * for \c command_line_args including argv[0]. This is useful if the standard + * library paths are relative to the binary. + */ +CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2FullArgv( + CXIndex CIdx, const char *source_filename, + const char *const *command_line_args, int num_command_line_args, + struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, + unsigned options, CXTranslationUnit *out_TU); + /** * \brief Flags that control how translation units are saved. * @@ -1573,7 +1590,7 @@ enum CXCursorKind { CXCursor_ObjCImplementationDecl = 18, /** \brief An Objective-C \@implementation for a category. */ CXCursor_ObjCCategoryImplDecl = 19, - /** \brief A typedef */ + /** \brief A typedef. */ CXCursor_TypedefDecl = 20, /** \brief A C++ class method. */ CXCursor_CXXMethod = 21, @@ -1982,7 +1999,11 @@ enum CXCursorKind { */ CXCursor_ObjCSelfExpr = 146, - CXCursor_LastExpr = CXCursor_ObjCSelfExpr, + /** \brief OpenMP 4.0 [2.4, Array Section]. + */ + CXCursor_OMPArraySectionExpr = 147, + + CXCursor_LastExpr = CXCursor_OMPArraySectionExpr, /* Statements */ CXCursor_FirstStmt = 200, @@ -2227,17 +2248,33 @@ enum CXCursorKind { /** \brief OpenMP taskgroup directive. */ - CXCursor_OMPTaskgroupDirective = 254, + CXCursor_OMPTaskgroupDirective = 254, /** \brief OpenMP cancellation point directive. */ - CXCursor_OMPCancellationPointDirective = 255, + CXCursor_OMPCancellationPointDirective = 255, /** \brief OpenMP cancel directive. */ - CXCursor_OMPCancelDirective = 256, + CXCursor_OMPCancelDirective = 256, - CXCursor_LastStmt = CXCursor_OMPCancelDirective, + /** \brief OpenMP target data directive. + */ + CXCursor_OMPTargetDataDirective = 257, + + /** \brief OpenMP taskloop directive. + */ + CXCursor_OMPTaskLoopDirective = 258, + + /** \brief OpenMP taskloop simd directive. + */ + CXCursor_OMPTaskLoopSimdDirective = 259, + + /** \brief OpenMP distribute directive. + */ + CXCursor_OMPDistributeDirective = 260, + + CXCursor_LastStmt = CXCursor_OMPDistributeDirective, /** * \brief Cursor that represents the translation unit itself. @@ -2271,7 +2308,10 @@ enum CXCursorKind { CXCursor_CUDAGlobalAttr = 414, CXCursor_CUDAHostAttr = 415, CXCursor_CUDASharedAttr = 416, - CXCursor_LastAttr = CXCursor_CUDASharedAttr, + CXCursor_VisibilityAttr = 417, + CXCursor_DLLExport = 418, + CXCursor_DLLImport = 419, + CXCursor_LastAttr = CXCursor_DLLImport, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -2287,8 +2327,9 @@ enum CXCursorKind { * \brief A module import declaration. */ CXCursor_ModuleImportDecl = 600, + CXCursor_TypeAliasTemplateDecl = 601, CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, - CXCursor_LastExtraDecl = CXCursor_ModuleImportDecl, + CXCursor_LastExtraDecl = CXCursor_TypeAliasTemplateDecl, /** * \brief A code completion overload candidate. @@ -2439,6 +2480,32 @@ enum CXLinkageKind { */ CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor); +enum CXVisibilityKind { + /** \brief This value indicates that no visibility information is available + * for a provided CXCursor. */ + CXVisibility_Invalid, + + /** \brief Symbol not seen by the linker. */ + CXVisibility_Hidden, + /** \brief Symbol seen by the linker but resolves to a symbol inside this object. */ + CXVisibility_Protected, + /** \brief Symbol seen by the linker and acts like a normal symbol. */ + CXVisibility_Default +}; + +/** + * \brief Describe the visibility of the entity referred to by a cursor. + * + * This returns the default visibility if not explicitly specified by + * a visibility attribute. The default visibility may be changed by + * commandline arguments. + * + * \param cursor The cursor to query. + * + * \returns The visibility of the cursor. + */ +CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor); + /** * \brief Determine the availability of the entity that this cursor refers to, * taking the current target platform into account. @@ -2558,7 +2625,6 @@ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); */ CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor); - /** * \brief A fast container representing a set of CXCursors. */ @@ -2851,7 +2917,8 @@ enum CXTypeKind { CXType_IncompleteArray = 114, CXType_VariableArray = 115, CXType_DependentSizedArray = 116, - CXType_MemberPointer = 117 + CXType_MemberPointer = 117, + CXType_Auto = 118 }; /** @@ -2876,7 +2943,6 @@ enum CXCallingConv { CXCallingConv_Unexposed = 200 }; - /** * \brief The type of an element in the abstract syntax tree. * @@ -3314,7 +3380,6 @@ CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C); */ CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C); - enum CXRefQualifierKind { /** \brief No ref-qualifier was provided. */ CXRefQualifier_None = 0, @@ -3443,7 +3508,6 @@ CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, * @{ */ - /** * \brief For cursors representing an iboutletcollection attribute, * this function returns the collection element type. @@ -3597,7 +3661,6 @@ CINDEX_LINKAGE CXString CINDEX_LINKAGE CXString clang_constructUSR_ObjCProtocol(const char *protocol_name); - /** * \brief Construct a USR for a specified Objective-C instance variable and * the USR for its containing class. @@ -3723,7 +3786,6 @@ CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor); */ CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor); - /** * \brief If the cursor points to a selector identifier in an Objective-C * method or message expression, this returns the selector index. @@ -3853,6 +3915,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C); */ CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor); +/** + * \brief Retrieve the CXStrings representing the mangled symbols of the C++ + * constructor or destructor at the cursor. + */ +CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor); + /** * @} */ @@ -3947,6 +4015,11 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, * @{ */ +/** + * \brief Determine if a C++ field is declared 'mutable'. + */ +CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C); + /** * \brief Determine if a C++ member function or member function template is * pure virtual. @@ -4939,8 +5012,7 @@ enum CXCursorKind clang_codeCompleteGetContainerKind( */ CINDEX_LINKAGE CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results); - - + /** * \brief Returns the currently-entered selector for an Objective-C message * send, formatted like "initWithFoo:bar:". Only guaranteed to return a @@ -4959,7 +5031,6 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); * @} */ - /** * \defgroup CINDEX_MISC Miscellaneous utility functions * @@ -4972,7 +5043,6 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); */ CINDEX_LINKAGE CXString clang_getClangVersion(void); - /** * \brief Enable/disable crash recovery. * @@ -5658,6 +5728,18 @@ CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction, CXTranslationUnit *out_TU, unsigned TU_options); +/** + * \brief Same as clang_indexSourceFile but requires a full command line + * for \c command_line_args including argv[0]. This is useful if the standard + * library paths are relative to the binary. + */ +CINDEX_LINKAGE int clang_indexSourceFileFullArgv( + CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, unsigned index_options, + const char *source_filename, const char *const *command_line_args, + int num_command_line_args, struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, CXTranslationUnit *out_TU, unsigned TU_options); + /** * \brief Index the given translation unit via callbacks implemented through * #IndexerCallbacks. @@ -5739,7 +5821,6 @@ CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, CXFieldVisitor visitor, CXClientData client_data); - /** * @} */ @@ -5752,4 +5833,3 @@ CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, } #endif #endif - diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index a2bd55a089ed..b66009e909a1 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -28,6 +28,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SanitizerBlacklist.h" @@ -70,6 +71,7 @@ namespace clang { class VTableContextBase; namespace Builtin { class Context; } + enum BuiltinTemplateKind : int; namespace comments { class FullComment; @@ -176,8 +178,9 @@ class ASTContext : public RefCountedBase { ClassScopeSpecializationPattern; /// \brief Mapping from materialized temporaries with static storage duration - /// that appear in constant initializers to their evaluated values. - llvm::DenseMap + /// that appear in constant initializers to their evaluated values. These are + /// allocated in a std::map because their address must be stable. + llvm::DenseMap MaterializedTemporaryValues; /// \brief Representation of a "canonical" template template parameter that @@ -215,6 +218,9 @@ class ASTContext : public RefCountedBase { /// __builtin_va_list type. mutable TypedefDecl *BuiltinVaListDecl; + /// The typedef for the predefined \c __builtin_ms_va_list type. + mutable TypedefDecl *BuiltinMSVaListDecl; + /// \brief The typedef for the predefined \c id type. mutable TypedefDecl *ObjCIdDecl; @@ -242,6 +248,9 @@ class ASTContext : public RefCountedBase { /// The identifier 'NSCopying'. IdentifierInfo *NSCopyingName = nullptr; + /// The identifier '__make_integer_seq'. + mutable IdentifierInfo *MakeIntegerSeqName = nullptr; + QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; @@ -395,6 +404,7 @@ class ASTContext : public RefCountedBase { TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; + mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -433,6 +443,7 @@ class ASTContext : public RefCountedBase { friend class CXXRecordDecl; const TargetInfo *Target; + const TargetInfo *AuxTarget; clang::PrintingPolicy PrintingPolicy; public: @@ -446,10 +457,59 @@ class ASTContext : public RefCountedBase { /// \brief Contains parents of a node. typedef llvm::SmallVector ParentVector; - /// \brief Maps from a node to its parents. + /// \brief Maps from a node to its parents. This is used for nodes that have + /// pointer identity only, which are more common and we can save space by + /// only storing a unique pointer to them. typedef llvm::DenseMap> ParentMap; + llvm::PointerUnion4> ParentMapPointers; + + /// Parent map for nodes without pointer identity. We store a full + /// DynTypedNode for all keys. + typedef llvm::DenseMap< + ast_type_traits::DynTypedNode, + llvm::PointerUnion4> + ParentMapOtherNodes; + + /// Container for either a single DynTypedNode or for an ArrayRef to + /// DynTypedNode. For use with ParentMap. + class DynTypedNodeList { + typedef ast_type_traits::DynTypedNode DynTypedNode; + llvm::AlignedCharArrayUnion> Storage; + bool IsSingleNode; + + public: + DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) { + new (Storage.buffer) DynTypedNode(N); + } + DynTypedNodeList(ArrayRef A) : IsSingleNode(false) { + new (Storage.buffer) ArrayRef(A); + } + + const ast_type_traits::DynTypedNode *begin() const { + if (!IsSingleNode) + return reinterpret_cast *>(Storage.buffer) + ->begin(); + return reinterpret_cast(Storage.buffer); + } + + const ast_type_traits::DynTypedNode *end() const { + if (!IsSingleNode) + return reinterpret_cast *>(Storage.buffer) + ->end(); + return reinterpret_cast(Storage.buffer) + 1; + } + + size_t size() const { return end() - begin(); } + bool empty() const { return begin() == end(); } + const DynTypedNode &operator[](size_t N) const { + assert(N < size() && "Out of bounds!"); + return *(begin() + N); + } + }; /// \brief Returns the parents of the given node. /// @@ -475,13 +535,11 @@ class ASTContext : public RefCountedBase { /// /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, /// NestedNameSpecifier or NestedNameSpecifierLoc. - template - ArrayRef getParents(const NodeT &Node) { + template DynTypedNodeList getParents(const NodeT &Node) { return getParents(ast_type_traits::DynTypedNode::create(Node)); } - ArrayRef - getParents(const ast_type_traits::DynTypedNode &Node); + DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node); const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; @@ -501,6 +559,9 @@ class ASTContext : public RefCountedBase { void *Allocate(size_t Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } + template T *Allocate(size_t Num = 1) const { + return static_cast(Allocate(Num * sizeof(T), llvm::alignOf())); + } void Deallocate(void *Ptr) const { } /// Return the total amount of physical memory allocated for representing @@ -516,7 +577,8 @@ class ASTContext : public RefCountedBase { } const TargetInfo &getTargetInfo() const { return *Target; } - + const TargetInfo *getAuxTargetInfo() const { return AuxTarget; } + /// getIntTypeForBitwidth - /// sets integer QualTy according to specified details: /// bitwidth, signed/unsigned. @@ -812,6 +874,7 @@ class ASTContext : public RefCountedBase { TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } ExternCContextDecl *getExternCContextDecl() const; + BuiltinTemplateDecl *getMakeIntegerSeqDecl() const; // Builtin Types. CanQualType VoidTy; @@ -835,17 +898,21 @@ class ASTContext : public RefCountedBase { CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; - CanQualType OCLImage2dTy, OCLImage2dArrayTy; + CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy; + CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy; + CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy; CanQualType OCLImage3dTy; - CanQualType OCLSamplerTy, OCLEventTy; + CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; + CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy; + CanQualType OMPArraySectionTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. - // Type used to help define __builtin_va_list for some targets. - // The type is built when constructing 'BuiltinVaListDecl'. - mutable QualType VaListTagTy; + // Decl used to help define __builtin_va_list for some targets. + // The decl is built when constructing 'BuiltinVaListDecl'. + mutable Decl *VaListTagDecl; ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins); @@ -881,6 +948,9 @@ class ASTContext : public RefCountedBase { void PrintStats() const; const SmallVectorImpl& getTypes() const { return Types; } + BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK, + const IdentifierInfo *II) const; + /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl /// declaration. RecordDecl *buildImplicitRecord(StringRef Name, @@ -955,6 +1025,9 @@ class ASTContext : public RefCountedBase { const FunctionType *adjustFunctionType(const FunctionType *Fn, FunctionType::ExtInfo EInfo); + /// Adjust the given function result type. + CanQualType getCanonicalFunctionResultType(QualType ResultType) const; + /// \brief Change the result type of a function type once it is deduced. void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType); @@ -1227,7 +1300,7 @@ class ASTContext : public RefCountedBase { UnaryTransformType::UTTKind UKind) const; /// \brief C++11 deduced auto type. - QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto, + QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent) const; /// \brief C++11 deduction pattern for 'auto' type. @@ -1381,6 +1454,12 @@ class ASTContext : public RefCountedBase { return NSCopyingName; } + IdentifierInfo *getMakeIntegerSeqName() const { + if (!MakeIntegerSeqName) + MakeIntegerSeqName = &Idents.get("__make_integer_seq"); + return MakeIntegerSeqName; + } + /// \brief Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; QualType getObjCInstanceType() { @@ -1569,7 +1648,16 @@ class ASTContext : public RefCountedBase { /// \brief Retrieve the C type declaration corresponding to the predefined /// \c __va_list_tag type used to help define the \c __builtin_va_list type /// for some targets. - QualType getVaListTagType() const; + Decl *getVaListTagDecl() const; + + /// Retrieve the C type declaration corresponding to the predefined + /// \c __builtin_ms_va_list type. + TypedefDecl *getBuiltinMSVaListDecl() const; + + /// Retrieve the type of the \c __builtin_ms_va_list type. + QualType getBuiltinMSVaListType() const { + return getTypeDeclType(getBuiltinMSVaListDecl()); + } /// \brief Return a type with additional \c const, \c volatile, or /// \c restrict qualifiers. @@ -1774,7 +1862,6 @@ class ASTContext : public RefCountedBase { /// record (struct/union/class) \p D, which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; - const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const; /// \brief Get or compute information about the layout of the specified /// Objective-C interface. @@ -2170,9 +2257,7 @@ class ASTContext : public RefCountedBase { const FunctionProtoType *FromFunctionType, const FunctionProtoType *ToFunctionType); - void ResetObjCLayout(const ObjCContainerDecl *CD) { - ObjCLayouts[CD] = nullptr; - } + void ResetObjCLayout(const ObjCContainerDecl *CD); //===--------------------------------------------------------------------===// // Integer Predicates @@ -2187,16 +2272,6 @@ class ASTContext : public RefCountedBase { // corresponding unsigned integer type. QualType getCorrespondingUnsignedType(QualType T) const; - //===--------------------------------------------------------------------===// - // Type Iterators. - //===--------------------------------------------------------------------===// - typedef llvm::iterator_range::const_iterator> - type_const_range; - - type_const_range types() const { - return type_const_range(Types.begin(), Types.end()); - } - //===--------------------------------------------------------------------===// // Integer Values //===--------------------------------------------------------------------===// @@ -2233,16 +2308,11 @@ class ASTContext : public RefCountedBase { /// \brief Get the duplicate declaration of a ObjCMethod in the same /// interface, or null if none exists. - const ObjCMethodDecl *getObjCMethodRedeclaration( - const ObjCMethodDecl *MD) const { - return ObjCMethodRedecls.lookup(MD); - } + const ObjCMethodDecl * + getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const; void setObjCMethodRedeclaration(const ObjCMethodDecl *MD, - const ObjCMethodDecl *Redecl) { - assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration"); - ObjCMethodRedecls[MD] = Redecl; - } + const ObjCMethodDecl *Redecl); /// \brief Returns the Objective-C interface that \p ND belongs to if it is /// an Objective-C method/property/ivar etc. that is part of an interface, @@ -2307,6 +2377,14 @@ class ASTContext : public RefCountedBase { Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, unsigned ParmIdx); + void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND); + + TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD); + + void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD); + + DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD); + void setManglingNumber(const NamedDecl *ND, unsigned Number); unsigned getManglingNumber(const NamedDecl *ND) const; @@ -2388,9 +2466,10 @@ class ASTContext : public RefCountedBase { /// This routine may only be invoked once for a given ASTContext object. /// It is normally invoked after ASTContext construction. /// - /// \param Target The target - void InitBuiltinTypes(const TargetInfo &Target); - + /// \param Target The target + void InitBuiltinTypes(const TargetInfo &Target, + const TargetInfo *AuxTarget = nullptr); + private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); @@ -2429,9 +2508,15 @@ class ASTContext : public RefCountedBase { /// \brief A set of deallocations that should be performed when the /// ASTContext is destroyed. - typedef llvm::SmallDenseMap > - DeallocationMap; - DeallocationMap Deallocations; + // FIXME: We really should have a better mechanism in the ASTContext to + // manage running destructors for types which do variable sized allocation + // within the AST. In some places we thread the AST bump pointer allocator + // into the datastructures which avoids this mess during deallocation but is + // wasteful of memory, and here we require a lot of error prone book keeping + // in order to track and run destructors while we're tearing things down. + typedef llvm::SmallVector, 16> + DeallocationFunctionsAndArguments; + DeallocationFunctionsAndArguments Deallocations; // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, @@ -2443,7 +2528,8 @@ class ASTContext : public RefCountedBase { void ReleaseDeclContextMaps(); void ReleaseParentMapEntries(); - std::unique_ptr AllParents; + std::unique_ptr PointerParents; + std::unique_ptr OtherParents; std::unique_ptr VTContext; diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index f4026e952643..3ff392de11a7 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -92,18 +92,6 @@ class ASTMutationListener { virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, const ObjCInterfaceDecl *IFD) {} - /// \brief A objc class extension redeclared or introduced a property. - /// - /// \param Prop the property in the class extension - /// - /// \param OrigProp the property from the original interface that was declared - /// or null if the property was introduced. - /// - /// \param ClassExt the class extension. - virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, - const ObjCPropertyDecl *OrigProp, - const ObjCCategoryDecl *ClassExt) {} - /// \brief A declaration is marked used which was not previously marked used. /// /// \param D the declaration marked used diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index dc3c34f28d94..dcaac802c110 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -106,18 +106,25 @@ class ASTNodeKind { } }; + /// Check if the given ASTNodeKind identifies a type that offers pointer + /// identity. This is useful for the fast path in DynTypedNode. + bool hasPointerIdentity() const { + return KindId > NKI_LastKindWithoutPointerIdentity; + } + private: /// \brief Kind ids. /// /// Includes all possible base and derived kinds. enum NodeKindId { NKI_None, - NKI_CXXCtorInitializer, NKI_TemplateArgument, - NKI_NestedNameSpecifier, NKI_NestedNameSpecifierLoc, NKI_QualType, NKI_TypeLoc, + NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc, + NKI_CXXCtorInitializer, + NKI_NestedNameSpecifier, NKI_Decl, #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl, #include "clang/AST/DeclNodes.inc" @@ -238,7 +245,11 @@ class DynTypedNode { /// Note that this is not supported by all AST nodes. For AST nodes /// that don't have a pointer-defined identity inside the AST, this /// method returns NULL. - const void *getMemoizationData() const { return MemoizationData; } + const void *getMemoizationData() const { + return NodeKind.hasPointerIdentity() + ? *reinterpret_cast(Storage.buffer) + : nullptr; + } /// \brief Prints the node to the given output stream. void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; @@ -257,6 +268,32 @@ class DynTypedNode { /// FIXME: Implement comparsion for other node types (currently /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data). bool operator<(const DynTypedNode &Other) const { + if (!NodeKind.isSame(Other.NodeKind)) + return NodeKind < Other.NodeKind; + + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return getUnchecked().getAsOpaquePtr() < + Other.getUnchecked().getAsOpaquePtr(); + + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) { + auto TLA = getUnchecked(); + auto TLB = Other.getUnchecked(); + return std::make_pair(TLA.getType().getAsOpaquePtr(), + TLA.getOpaqueData()) < + std::make_pair(TLB.getType().getAsOpaquePtr(), + TLB.getOpaqueData()); + } + + if (ASTNodeKind::getFromNodeKind().isSame( + NodeKind)) { + auto NNSLA = getUnchecked(); + auto NNSLB = Other.getUnchecked(); + return std::make_pair(NNSLA.getNestedNameSpecifier(), + NNSLA.getOpaqueData()) < + std::make_pair(NNSLB.getNestedNameSpecifier(), + NNSLB.getOpaqueData()); + } + assert(getMemoizationData() && Other.getMemoizationData()); return getMemoizationData() < Other.getMemoizationData(); } @@ -270,6 +307,13 @@ class DynTypedNode { if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) return getUnchecked() == Other.getUnchecked(); + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return getUnchecked() == Other.getUnchecked(); + + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return getUnchecked() == + Other.getUnchecked(); + assert(getMemoizationData() && Other.getMemoizationData()); return getMemoizationData() == Other.getMemoizationData(); } @@ -278,6 +322,47 @@ class DynTypedNode { } /// @} + /// \brief Hooks for using DynTypedNode as a key in a DenseMap. + struct DenseMapInfo { + static inline DynTypedNode getEmptyKey() { + DynTypedNode Node; + Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey(); + return Node; + } + static inline DynTypedNode getTombstoneKey() { + DynTypedNode Node; + Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey(); + return Node; + } + static unsigned getHashValue(const DynTypedNode &Val) { + // FIXME: Add hashing support for the remaining types. + if (ASTNodeKind::getFromNodeKind().isSame(Val.NodeKind)) { + auto TL = Val.getUnchecked(); + return llvm::hash_combine(TL.getType().getAsOpaquePtr(), + TL.getOpaqueData()); + } + + if (ASTNodeKind::getFromNodeKind().isSame( + Val.NodeKind)) { + auto NNSL = Val.getUnchecked(); + return llvm::hash_combine(NNSL.getNestedNameSpecifier(), + NNSL.getOpaqueData()); + } + + assert(Val.getMemoizationData()); + return llvm::hash_value(Val.getMemoizationData()); + } + static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) { + auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey(); + auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey(); + return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) && + ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) || + (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) && + ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) || + LHS == RHS; + } + }; + private: /// \brief Takes care of converting from and to \c T. template struct BaseConverter; @@ -286,18 +371,18 @@ class DynTypedNode { template struct DynCastPtrConverter { static const T *get(ASTNodeKind NodeKind, const char Storage[]) { if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) - return cast(*reinterpret_cast(Storage)); + return &getUnchecked(NodeKind, Storage); return nullptr; } static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { assert(ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)); - return *cast(*reinterpret_cast(Storage)); + return *cast(static_cast( + *reinterpret_cast(Storage))); } static DynTypedNode create(const BaseT &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNode(Node); - Result.MemoizationData = &Node; - new (Result.Storage.buffer) const BaseT * (&Node); + new (Result.Storage.buffer) const void *(&Node); return Result; } }; @@ -306,18 +391,18 @@ class DynTypedNode { template struct PtrConverter { static const T *get(ASTNodeKind NodeKind, const char Storage[]) { if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) - return *reinterpret_cast(Storage); + return &getUnchecked(NodeKind, Storage); return nullptr; } static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { assert(ASTNodeKind::getFromNodeKind().isSame(NodeKind)); - return **reinterpret_cast(Storage); + return *static_cast( + *reinterpret_cast(Storage)); } static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind(); - Result.MemoizationData = &Node; - new (Result.Storage.buffer) const T * (&Node); + new (Result.Storage.buffer) const void *(&Node); return Result; } }; @@ -336,14 +421,12 @@ class DynTypedNode { static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind(); - Result.MemoizationData = nullptr; new (Result.Storage.buffer) T(Node); return Result; } }; ASTNodeKind NodeKind; - const void *MemoizationData; /// \brief Stores the data of the node. /// @@ -353,12 +436,9 @@ class DynTypedNode { /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and /// \c TemplateArguments on the other hand do not have storage or unique /// pointers and thus need to be stored by value. - typedef llvm::AlignedCharArrayUnion< - Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *> - KindsByPointer; - llvm::AlignedCharArrayUnion - Storage; + llvm::AlignedCharArrayUnion Storage; }; template @@ -420,6 +500,10 @@ template <> struct DenseMapInfo : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {}; +template <> +struct DenseMapInfo + : clang::ast_type_traits::DynTypedNode::DenseMapInfo {}; + } // end namespace llvm #endif diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 4e282d68b748..8b80e9f6396e 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -56,21 +56,21 @@ class Attr { bool IsLateParsed : 1; bool DuplicatesAllowed : 1; - void* operator new(size_t bytes) throw() { + void *operator new(size_t bytes) LLVM_NOEXCEPT { llvm_unreachable("Attrs cannot be allocated with regular 'new'."); } - void operator delete(void* data) throw() { + void operator delete(void *data) LLVM_NOEXCEPT { llvm_unreachable("Attrs cannot be released with regular 'delete'."); } public: // Forward so that the regular new and delete do not hide global ones. - void* operator new(size_t Bytes, ASTContext &C, - size_t Alignment = 8) throw() { + void *operator new(size_t Bytes, ASTContext &C, + size_t Alignment = 8) LLVM_NOEXCEPT { return ::operator new(Bytes, C, Alignment); } void operator delete(void *Ptr, ASTContext &C, - size_t Alignment) throw() { + size_t Alignment) LLVM_NOEXCEPT { return ::operator delete(Ptr, C, Alignment); } diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index 488cacef0af3..85e237a2bf04 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -160,6 +160,12 @@ 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. @@ -168,6 +174,18 @@ BUILTIN_TYPE(OCLSampler, OCLSamplerTy) // OpenCL event_t. BUILTIN_TYPE(OCLEvent, OCLEventTy) +// OpenCL clk_event_t. +BUILTIN_TYPE(OCLClkEvent, OCLClkEventTy) + +// OpenCL queue_t. +BUILTIN_TYPE(OCLQueue, OCLQueueTy) + +// OpenCL ndrange_t. +BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy) + +// OpenCL reserve_id_t. +BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy) + // This represents the type of an expression whose type is // totally unknown, e.g. 'T::foo'. It is permitted for this to // appear in situations where the structure of the type is @@ -227,8 +245,11 @@ PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy) // context. PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) +// A placeholder type for OpenMP array sections. +PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(ARCUnbridgedCast) +LAST_BUILTIN_TYPE(OMPArraySection) #undef LAST_BUILTIN_TYPE #endif diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index f7612f21f216..8587260049a0 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -155,17 +155,16 @@ class CXXBasePaths { /// \brief Array of the declarations that have been found. This /// array is constructed only if needed, e.g., to iterate over the /// results within LookupResult. - NamedDecl **DeclsFound; + std::unique_ptr DeclsFound; unsigned NumDeclsFound; friend class CXXRecordDecl; void ComputeDeclsFound(); - bool lookupInBases(ASTContext &Context, - const CXXRecordDecl *Record, - CXXRecordDecl::BaseMatchesCallback *BaseMatches, - void *UserData); + bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record, + CXXRecordDecl::BaseMatchesCallback BaseMatches); + public: typedef std::list::iterator paths_iterator; typedef std::list::const_iterator const_paths_iterator; @@ -173,15 +172,12 @@ class CXXBasePaths { /// BasePaths - Construct a new BasePaths structure to record the /// paths for a derived-to-base search. - explicit CXXBasePaths(bool FindAmbiguities = true, - bool RecordPaths = true, + explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true, bool DetectVirtual = true) - : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), - DetectVirtual(DetectVirtual), DetectedVirtual(nullptr), - DeclsFound(nullptr), NumDeclsFound(0) { } - - ~CXXBasePaths() { delete [] DeclsFound; } - + : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), + DetectVirtual(DetectVirtual), DetectedVirtual(nullptr), + NumDeclsFound(0) {} + paths_iterator begin() { return Paths.begin(); } paths_iterator end() { return Paths.end(); } const_paths_iterator begin() const { return Paths.begin(); } diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 72ca9f5cd67d..1d22bccd2e89 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -130,6 +130,14 @@ namespace clang { return (Quantity & -Quantity) == Quantity; } + /// Test whether this is a multiple of the other value. + /// + /// Among other things, this promises that + /// self.RoundUpToAlignment(N) will just return self. + bool isMultipleOf(CharUnits N) const { + return (*this % N) == 0; + } + // Arithmetic operators. CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); @@ -172,10 +180,20 @@ namespace clang { /// Given that this is a non-zero alignment value, what is the /// alignment at the given offset? - CharUnits alignmentAtOffset(CharUnits offset) { + CharUnits alignmentAtOffset(CharUnits offset) const { + assert(Quantity != 0 && "offsetting from unknown alignment?"); return CharUnits(llvm::MinAlign(Quantity, offset.Quantity)); } + /// Given that this is the alignment of the first element of an + /// array, return the minimum alignment of any element in the array. + CharUnits alignmentOfArrayElement(CharUnits elementSize) const { + // Since we don't track offsetted alignments, the alignment of + // the second element (or any odd element) will be minimally + // aligned. + return alignmentAtOffset(elementSize); + } + }; // class CharUnit } // namespace clang diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 9b05d397baf8..6a803836e848 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -79,12 +79,8 @@ class Sema { /// Returns a copy of array, owned by Sema's allocator. template ArrayRef copyArray(ArrayRef Source) { - size_t Size = Source.size(); - if (Size != 0) { - T *Mem = Allocator.Allocate(Size); - std::uninitialized_copy(Source.begin(), Source.end(), Mem); - return llvm::makeArrayRef(Mem, Size); - } + if (!Source.empty()) + return Source.copy(Allocator); return None; } diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h deleted file mode 100644 index dd167fe27c02..000000000000 --- a/include/clang/AST/DataRecursiveASTVisitor.h +++ /dev/null @@ -1,2691 +0,0 @@ -//===--- DataRecursiveASTVisitor.h - Data-Recursive AST Visitor -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the DataRecursiveASTVisitor interface, which recursively -// traverses the entire AST, using data recursion for Stmts/Exprs. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H -#define LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H - -#include "clang/AST/Attr.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclFriend.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/DeclOpenMP.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ExprCXX.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/NestedNameSpecifier.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/StmtCXX.h" -#include "clang/AST/StmtObjC.h" -#include "clang/AST/StmtOpenMP.h" -#include "clang/AST/TemplateBase.h" -#include "clang/AST/TemplateName.h" -#include "clang/AST/Type.h" -#include "clang/AST/TypeLoc.h" - -// The following three macros are used for meta programming. The code -// using them is responsible for defining macro OPERATOR(). - -// All unary operators. -#define UNARYOP_LIST() \ - OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \ - OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \ - OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \ - OPERATOR(Extension) - -// All binary operators (excluding compound assign operators). -#define BINOP_LIST() \ - OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \ - OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \ - OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \ - OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \ - OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma) - -// All compound assign operators. -#define CAO_LIST() \ - OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \ - OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor) - -namespace clang { - -// Reduce the diff between RecursiveASTVisitor / DataRecursiveASTVisitor to -// make it easier to track changes and keep the two in sync. -#define RecursiveASTVisitor DataRecursiveASTVisitor - -// A helper macro to implement short-circuiting when recursing. It -// invokes CALL_EXPR, which must be a method call, on the derived -// object (s.t. a user of RecursiveASTVisitor can override the method -// in CALL_EXPR). -#define TRY_TO(CALL_EXPR) \ - do { \ - if (!getDerived().CALL_EXPR) \ - return false; \ - } while (0) - -/// \brief A class that does preorder 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); -/// 2. at a given node, walk up the class hierarchy, starting from -/// the node's dynamic type, until the top-most class (e.g. Stmt, -/// Decl, or Type) is reached. -/// 3. given a (node, class) combination, where 'class' is some base -/// class of the dynamic type of 'node', call a user-overridable -/// function to actually visit the node. -/// -/// These tasks are done by three groups of methods, respectively: -/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point -/// for traversing an AST rooted at x. This method simply -/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo -/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and -/// then recursively visits the child nodes of x. -/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work -/// similarly. -/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit -/// any child node of x. Instead, it first calls WalkUpFromBar(x) -/// where Bar is the direct parent class of Foo (unless Foo has -/// no parent), and then calls VisitFoo(x) (see the next list item). -/// 3. VisitFoo(Foo *x) does task #3. -/// -/// These three method groups are tiered (Traverse* > WalkUpFrom* > -/// Visit*). A method (e.g. Traverse*) may call methods from the same -/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*). -/// It may not call methods from a higher tier. -/// -/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar -/// is Foo's super class) before calling VisitFoo(), the result is -/// that the Visit*() methods for a given node are called in the -/// top-down order (e.g. for a node of type NamespaceDecl, the order will -/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()). -/// -/// This scheme guarantees that all Visit*() calls for the same AST -/// node are grouped together. In other words, Visit*() methods for -/// different nodes are never interleaved. -/// -/// Stmts are traversed internally using a data queue to avoid a stack overflow -/// with hugely nested ASTs. -/// -/// Clients of this visitor should subclass the visitor (providing -/// themselves as the template argument, using the curiously recurring -/// template pattern) and override any of the Traverse*, WalkUpFrom*, -/// and Visit* methods for declarations, types, statements, -/// expressions, or other AST nodes where the visitor should customize -/// behavior. Most users only need to override Visit*. Advanced -/// users may override Traverse* and WalkUpFrom* to implement custom -/// traversal strategies. Returning false from one of these overridden -/// functions will abort the entire traversal. -/// -/// By default, this visitor tries to visit every part of the explicit -/// source code exactly once. The default policy towards templates -/// is to descend into the 'pattern' class or function body, not any -/// explicit or implicit instantiations. Explicit specializations -/// are still visited, and the patterns of partial specializations -/// are visited separately. This behavior can be changed by -/// overriding shouldVisitTemplateInstantiations() in the derived class -/// 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. -template class RecursiveASTVisitor { -public: - /// \brief Return a reference to the derived class. - Derived &getDerived() { return *static_cast(this); } - - /// \brief Return whether this visitor should recurse into - /// template instantiations. - bool shouldVisitTemplateInstantiations() const { return false; } - - /// \brief Return whether this visitor should recurse into the types of - /// TypeLocs. - bool shouldWalkTypesOfTypeLocs() const { return true; } - - /// \brief Recursively visit a statement or expression, by - /// dispatching to Traverse*() based on the argument's dynamic type. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is NULL). - bool TraverseStmt(Stmt *S); - - /// \brief Recursively visit a type, by dispatching to - /// Traverse*Type() based on the argument's getTypeClass() property. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is a Null type). - bool TraverseType(QualType T); - - /// \brief Recursively visit a type with location, by dispatching to - /// Traverse*TypeLoc() based on the argument type's getTypeClass() property. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is a Null type location). - bool TraverseTypeLoc(TypeLoc TL); - - /// \brief Recursively visit an attribute, by dispatching to - /// Traverse*Attr() based on the argument's dynamic type. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is a Null type location). - bool TraverseAttr(Attr *At); - - /// \brief Recursively visit a declaration, by dispatching to - /// Traverse*Decl() based on the argument's dynamic type. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is NULL). - bool TraverseDecl(Decl *D); - - /// \brief Recursively visit a C++ nested-name-specifier. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); - - /// \brief Recursively visit a C++ nested-name-specifier with location - /// information. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); - - /// \brief Recursively visit a name with its location information. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo); - - /// \brief Recursively visit a template name and dispatch to the - /// appropriate method. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseTemplateName(TemplateName Template); - - /// \brief Recursively visit a template argument and dispatch to the - /// appropriate method for the argument type. - /// - /// \returns false if the visitation was terminated early, true otherwise. - // FIXME: migrate callers to TemplateArgumentLoc instead. - bool TraverseTemplateArgument(const TemplateArgument &Arg); - - /// \brief Recursively visit a template argument location and dispatch to the - /// appropriate method for the argument type. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc); - - /// \brief Recursively visit a set of template arguments. - /// This can be overridden by a subclass, but it's not expected that - /// will be needed -- this visitor always dispatches to another. - /// - /// \returns false if the visitation was terminated early, true otherwise. - // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead. - bool TraverseTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs); - - /// \brief Recursively visit a constructor initializer. This - /// automatically dispatches to another visitor for the initializer - /// expression, but not for the name of the initializer, so may - /// be overridden for clients that need access to the name. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseConstructorInitializer(CXXCtorInitializer *Init); - - /// \brief Recursively visit a lambda capture. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C); - - /// \brief Recursively visit the body of a lambda expression. - /// - /// This provides a hook for visitors that need more context when visiting - /// \c LE->getBody(). - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaBody(LambdaExpr *LE); - - // ---- Methods on Attrs ---- - - // \brief Visit an attribute. - bool VisitAttr(Attr *A) { return true; } - -// Declare Traverse* and empty Visit* for all Attr classes. -#define ATTR_VISITOR_DECLS_ONLY -#include "clang/AST/AttrVisitor.inc" -#undef ATTR_VISITOR_DECLS_ONLY - -// ---- Methods on Stmts ---- - -// Declare Traverse*() for all concrete Stmt classes. -#define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S); -#include "clang/AST/StmtNodes.inc" - // The above header #undefs ABSTRACT_STMT and STMT upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all Stmt classes. - bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); } - bool VisitStmt(Stmt *S) { return true; } -#define STMT(CLASS, PARENT) \ - bool WalkUpFrom##CLASS(CLASS *S) { \ - TRY_TO(WalkUpFrom##PARENT(S)); \ - TRY_TO(Visit##CLASS(S)); \ - return true; \ - } \ - bool Visit##CLASS(CLASS *S) { return true; } -#include "clang/AST/StmtNodes.inc" - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary -// operator methods. Unary operators are not classes in themselves -// (they're all opcodes in UnaryOperator) but do have visitors. -#define OPERATOR(NAME) \ - bool TraverseUnary##NAME(UnaryOperator *S) { \ - TRY_TO(WalkUpFromUnary##NAME(S)); \ - StmtQueueAction StmtQueue(*this); \ - StmtQueue.queue(S->getSubExpr()); \ - return true; \ - } \ - bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ - TRY_TO(WalkUpFromUnaryOperator(S)); \ - TRY_TO(VisitUnary##NAME(S)); \ - return true; \ - } \ - bool VisitUnary##NAME(UnaryOperator *S) { return true; } - - UNARYOP_LIST() -#undef OPERATOR - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary -// operator methods. Binary operators are not classes in themselves -// (they're all opcodes in BinaryOperator) but do have visitors. -#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \ - bool TraverseBin##NAME(BINOP_TYPE *S) { \ - TRY_TO(WalkUpFromBin##NAME(S)); \ - StmtQueueAction StmtQueue(*this); \ - StmtQueue.queue(S->getLHS()); \ - StmtQueue.queue(S->getRHS()); \ - return true; \ - } \ - bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ - TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \ - TRY_TO(VisitBin##NAME(S)); \ - return true; \ - } \ - bool VisitBin##NAME(BINOP_TYPE *S) { return true; } - -#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator) - BINOP_LIST() -#undef OPERATOR - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound -// assignment methods. Compound assignment operators are not -// classes in themselves (they're all opcodes in -// CompoundAssignOperator) but do have visitors. -#define OPERATOR(NAME) \ - GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator) - - CAO_LIST() -#undef OPERATOR -#undef GENERAL_BINOP_FALLBACK - -// ---- Methods on Types ---- -// FIXME: revamp to take TypeLoc's rather than Types. - -// Declare Traverse*() for all concrete Type classes. -#define ABSTRACT_TYPE(CLASS, BASE) -#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T); -#include "clang/AST/TypeNodes.def" - // The above header #undefs ABSTRACT_TYPE and TYPE upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all Type classes. - bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); } - bool VisitType(Type *T) { return true; } -#define TYPE(CLASS, BASE) \ - bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \ - TRY_TO(WalkUpFrom##BASE(T)); \ - TRY_TO(Visit##CLASS##Type(T)); \ - return true; \ - } \ - bool Visit##CLASS##Type(CLASS##Type *T) { return true; } -#include "clang/AST/TypeNodes.def" - -// ---- Methods on TypeLocs ---- -// FIXME: this currently just calls the matching Type methods - -// Declare Traverse*() for all concrete TypeLoc classes. -#define ABSTRACT_TYPELOC(CLASS, BASE) -#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); -#include "clang/AST/TypeLocNodes.def" - // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes. - bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); } - bool VisitTypeLoc(TypeLoc TL) { return true; } - - // QualifiedTypeLoc and UnqualTypeLoc are not declared in - // TypeNodes.def and thus need to be handled specially. - bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) { - return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); - } - bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; } - bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) { - return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); - } - bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; } - -// Note that BASE includes trailing 'Type' which CLASS doesn't. -#define TYPE(CLASS, BASE) \ - bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ - TRY_TO(WalkUpFrom##BASE##Loc(TL)); \ - TRY_TO(Visit##CLASS##TypeLoc(TL)); \ - return true; \ - } \ - bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; } -#include "clang/AST/TypeNodes.def" - -// ---- Methods on Decls ---- - -// Declare Traverse*() for all concrete Decl classes. -#define ABSTRACT_DECL(DECL) -#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D); -#include "clang/AST/DeclNodes.inc" - // The above header #undefs ABSTRACT_DECL and DECL upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all Decl classes. - bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); } - bool VisitDecl(Decl *D) { return true; } -#define DECL(CLASS, BASE) \ - bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \ - TRY_TO(WalkUpFrom##BASE(D)); \ - TRY_TO(Visit##CLASS##Decl(D)); \ - return true; \ - } \ - bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } -#include "clang/AST/DeclNodes.inc" - -private: - // These are helper methods used by more than one Traverse* method. - bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); - bool TraverseClassInstantiations(ClassTemplateDecl *D); - bool TraverseVariableInstantiations(VarTemplateDecl *D); - bool TraverseFunctionInstantiations(FunctionTemplateDecl *D); - bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, - unsigned Count); - bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); - bool TraverseRecordHelper(RecordDecl *D); - bool TraverseCXXRecordHelper(CXXRecordDecl *D); - bool TraverseDeclaratorHelper(DeclaratorDecl *D); - bool TraverseDeclContextHelper(DeclContext *DC); - bool TraverseFunctionHelper(FunctionDecl *D); - bool TraverseVarHelper(VarDecl *D); - bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); - bool TraverseOMPLoopDirective(OMPLoopDirective *S); - bool TraverseOMPClause(OMPClause *C); -#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" - /// \brief Process clauses with list of variables. - template bool VisitOMPClauseList(T *Node); - - typedef SmallVector StmtsTy; - typedef SmallVector QueuesTy; - - QueuesTy Queues; - - class NewQueueRAII { - RecursiveASTVisitor &RAV; - - public: - NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) { - RAV.Queues.push_back(&queue); - } - ~NewQueueRAII() { RAV.Queues.pop_back(); } - }; - - StmtsTy &getCurrentQueue() { - assert(!Queues.empty() && "base TraverseStmt was never called?"); - return *Queues.back(); - } - -public: - class StmtQueueAction { - StmtsTy &CurrQueue; - - public: - explicit StmtQueueAction(RecursiveASTVisitor &RAV) - : CurrQueue(RAV.getCurrentQueue()) {} - - void queue(Stmt *S) { CurrQueue.push_back(S); } - }; -}; - -#define DISPATCH(NAME, CLASS, VAR) \ - return getDerived().Traverse##NAME(static_cast(VAR)) - -template -bool RecursiveASTVisitor::TraverseStmt(Stmt *S) { - if (!S) - return true; - - StmtsTy Queue, StmtsToEnqueue; - Queue.push_back(S); - NewQueueRAII NQ(StmtsToEnqueue, *this); - - while (!Queue.empty()) { - S = Queue.pop_back_val(); - if (!S) - continue; - - StmtsToEnqueue.clear(); - -#define DISPATCH_STMT(NAME, CLASS, VAR) \ - TRY_TO(Traverse##NAME(static_cast(VAR))); \ - break - - // If we have a binary expr, dispatch to the subcode of the binop. A smart - // optimizer (e.g. LLVM) will fold this comparison into the switch stmt - // below. - if (BinaryOperator *BinOp = dyn_cast(S)) { - switch (BinOp->getOpcode()) { -#define OPERATOR(NAME) \ - case BO_##NAME: \ - DISPATCH_STMT(Bin##NAME, BinaryOperator, S); - - BINOP_LIST() -#undef OPERATOR -#undef BINOP_LIST - -#define OPERATOR(NAME) \ - case BO_##NAME##Assign: \ - DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S); - - CAO_LIST() -#undef OPERATOR -#undef CAO_LIST - } - } else if (UnaryOperator *UnOp = dyn_cast(S)) { - switch (UnOp->getOpcode()) { -#define OPERATOR(NAME) \ - case UO_##NAME: \ - DISPATCH_STMT(Unary##NAME, UnaryOperator, S); - - UNARYOP_LIST() -#undef OPERATOR -#undef UNARYOP_LIST - } - } else { - - // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. - switch (S->getStmtClass()) { - case Stmt::NoStmtClass: - break; -#define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) \ - case Stmt::CLASS##Class: \ - DISPATCH_STMT(CLASS, CLASS, S); -#include "clang/AST/StmtNodes.inc" - } - } - - Queue.append(StmtsToEnqueue.rbegin(), StmtsToEnqueue.rend()); - } - - return true; -} - -#undef DISPATCH_STMT - -template -bool RecursiveASTVisitor::TraverseType(QualType T) { - if (T.isNull()) - return true; - - switch (T->getTypeClass()) { -#define ABSTRACT_TYPE(CLASS, BASE) -#define TYPE(CLASS, BASE) \ - case Type::CLASS: \ - DISPATCH(CLASS##Type, CLASS##Type, const_cast(T.getTypePtr())); -#include "clang/AST/TypeNodes.def" - } - - return true; -} - -template -bool RecursiveASTVisitor::TraverseTypeLoc(TypeLoc TL) { - if (TL.isNull()) - return true; - - switch (TL.getTypeLocClass()) { -#define ABSTRACT_TYPELOC(CLASS, BASE) -#define TYPELOC(CLASS, BASE) \ - case TypeLoc::CLASS: \ - return getDerived().Traverse##CLASS##TypeLoc(TL.castAs()); -#include "clang/AST/TypeLocNodes.def" - } - - return true; -} - -// Define the Traverse*Attr(Attr* A) methods -#define VISITORCLASS RecursiveASTVisitor -#include "clang/AST/AttrVisitor.inc" -#undef VISITORCLASS - -template -bool RecursiveASTVisitor::TraverseDecl(Decl *D) { - if (!D) - return true; - - // As a syntax visitor, we want to ignore declarations for - // implicitly-defined declarations (ones not typed explicitly by the - // user). - if (D->isImplicit()) - return true; - - switch (D->getKind()) { -#define ABSTRACT_DECL(DECL) -#define DECL(CLASS, BASE) \ - case Decl::CLASS: \ - if (!getDerived().Traverse##CLASS##Decl(static_cast(D))) \ - return false; \ - break; -#include "clang/AST/DeclNodes.inc" - } - - // Visit any attributes attached to this declaration. - for (auto *I : D->attrs()) { - if (!getDerived().TraverseAttr(I)) - return false; - } - return true; -} - -#undef DISPATCH - -template -bool RecursiveASTVisitor::TraverseNestedNameSpecifier( - NestedNameSpecifier *NNS) { - if (!NNS) - return true; - - if (NNS->getPrefix()) - TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix())); - - switch (NNS->getKind()) { - case NestedNameSpecifier::Identifier: - case NestedNameSpecifier::Namespace: - case NestedNameSpecifier::NamespaceAlias: - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Super: - return true; - - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - TRY_TO(TraverseType(QualType(NNS->getAsType(), 0))); - } - - return true; -} - -template -bool RecursiveASTVisitor::TraverseNestedNameSpecifierLoc( - NestedNameSpecifierLoc NNS) { - if (!NNS) - return true; - - if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) - TRY_TO(TraverseNestedNameSpecifierLoc(Prefix)); - - switch (NNS.getNestedNameSpecifier()->getKind()) { - case NestedNameSpecifier::Identifier: - case NestedNameSpecifier::Namespace: - case NestedNameSpecifier::NamespaceAlias: - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Super: - return true; - - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - TRY_TO(TraverseTypeLoc(NNS.getTypeLoc())); - break; - } - - return true; -} - -template -bool RecursiveASTVisitor::TraverseDeclarationNameInfo( - DeclarationNameInfo NameInfo) { - switch (NameInfo.getName().getNameKind()) { - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) - TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc())); - - break; - - case DeclarationName::Identifier: - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - case DeclarationName::CXXOperatorName: - case DeclarationName::CXXLiteralOperatorName: - case DeclarationName::CXXUsingDirective: - break; - } - - return true; -} - -template -bool RecursiveASTVisitor::TraverseTemplateName(TemplateName Template) { - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) - TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier())); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); - - return true; -} - -template -bool RecursiveASTVisitor::TraverseTemplateArgument( - const TemplateArgument &Arg) { - switch (Arg.getKind()) { - case TemplateArgument::Null: - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::NullPtr: - return true; - - case TemplateArgument::Type: - return getDerived().TraverseType(Arg.getAsType()); - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: - return getDerived().TraverseTemplateName( - Arg.getAsTemplateOrTemplatePattern()); - - case TemplateArgument::Expression: - return getDerived().TraverseStmt(Arg.getAsExpr()); - - case TemplateArgument::Pack: - return getDerived().TraverseTemplateArguments(Arg.pack_begin(), - Arg.pack_size()); - } - - return true; -} - -// FIXME: no template name location? -// FIXME: no source locations for a template argument pack? -template -bool RecursiveASTVisitor::TraverseTemplateArgumentLoc( - const TemplateArgumentLoc &ArgLoc) { - const TemplateArgument &Arg = ArgLoc.getArgument(); - - switch (Arg.getKind()) { - case TemplateArgument::Null: - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::NullPtr: - return true; - - case TemplateArgument::Type: { - // FIXME: how can TSI ever be NULL? - if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo()) - return getDerived().TraverseTypeLoc(TSI->getTypeLoc()); - else - return getDerived().TraverseType(Arg.getAsType()); - } - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: - if (ArgLoc.getTemplateQualifierLoc()) - TRY_TO(getDerived().TraverseNestedNameSpecifierLoc( - ArgLoc.getTemplateQualifierLoc())); - return getDerived().TraverseTemplateName( - Arg.getAsTemplateOrTemplatePattern()); - - case TemplateArgument::Expression: - return getDerived().TraverseStmt(ArgLoc.getSourceExpression()); - - case TemplateArgument::Pack: - return getDerived().TraverseTemplateArguments(Arg.pack_begin(), - Arg.pack_size()); - } - - return true; -} - -template -bool RecursiveASTVisitor::TraverseTemplateArguments( - const TemplateArgument *Args, unsigned NumArgs) { - for (unsigned I = 0; I != NumArgs; ++I) { - TRY_TO(TraverseTemplateArgument(Args[I])); - } - - return true; -} - -template -bool RecursiveASTVisitor::TraverseConstructorInitializer( - CXXCtorInitializer *Init) { - if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) - TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); - - if (Init->isWritten()) - TRY_TO(TraverseStmt(Init->getInit())); - return true; -} - -template -bool -RecursiveASTVisitor::TraverseLambdaCapture(LambdaExpr *LE, - const LambdaCapture *C) { - if (LE->isInitCapture(C)) - TRY_TO(TraverseDecl(C->getCapturedVar())); - return true; -} - -template -bool RecursiveASTVisitor::TraverseLambdaBody(LambdaExpr *LE) { - StmtQueueAction StmtQueue(*this); - StmtQueue.queue(LE->getBody()); - return true; -} - -// ----------------- Type traversal ----------------- - -// This macro makes available a variable T, the passed-in type. -#define DEF_TRAVERSE_TYPE(TYPE, CODE) \ - template \ - bool RecursiveASTVisitor::Traverse##TYPE(TYPE *T) { \ - TRY_TO(WalkUpFrom##TYPE(T)); \ - { CODE; } \ - return true; \ - } - -DEF_TRAVERSE_TYPE(BuiltinType, {}) - -DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(BlockPointerType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(LValueReferenceType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(RValueReferenceType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(MemberPointerType, { - TRY_TO(TraverseType(QualType(T->getClass(), 0))); - TRY_TO(TraverseType(T->getPointeeType())); -}) - -DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); }) - -DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); }) - -DEF_TRAVERSE_TYPE(ConstantArrayType, - { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(IncompleteArrayType, - { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(VariableArrayType, { - TRY_TO(TraverseType(T->getElementType())); - TRY_TO(TraverseStmt(T->getSizeExpr())); -}) - -DEF_TRAVERSE_TYPE(DependentSizedArrayType, { - TRY_TO(TraverseType(T->getElementType())); - if (T->getSizeExpr()) - TRY_TO(TraverseStmt(T->getSizeExpr())); -}) - -DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, { - if (T->getSizeExpr()) - TRY_TO(TraverseStmt(T->getSizeExpr())); - TRY_TO(TraverseType(T->getElementType())); -}) - -DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(FunctionNoProtoType, - { TRY_TO(TraverseType(T->getReturnType())); }) - -DEF_TRAVERSE_TYPE(FunctionProtoType, { - TRY_TO(TraverseType(T->getReturnType())); - - for (const auto &A : T->param_types()) { - TRY_TO(TraverseType(A)); - } - - for (const auto &E : T->exceptions()) { - TRY_TO(TraverseType(E)); - } - - if (Expr *NE = T->getNoexceptExpr()) - TRY_TO(TraverseStmt(NE)); -}) - -DEF_TRAVERSE_TYPE(UnresolvedUsingType, {}) -DEF_TRAVERSE_TYPE(TypedefType, {}) - -DEF_TRAVERSE_TYPE(TypeOfExprType, - { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) - -DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); }) - -DEF_TRAVERSE_TYPE(DecltypeType, - { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) - -DEF_TRAVERSE_TYPE(UnaryTransformType, { - TRY_TO(TraverseType(T->getBaseType())); - TRY_TO(TraverseType(T->getUnderlyingType())); -}) - -DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); }) - -DEF_TRAVERSE_TYPE(RecordType, {}) -DEF_TRAVERSE_TYPE(EnumType, {}) -DEF_TRAVERSE_TYPE(TemplateTypeParmType, {}) -DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {}) -DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {}) - -DEF_TRAVERSE_TYPE(TemplateSpecializationType, { - TRY_TO(TraverseTemplateName(T->getTemplateName())); - TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); -}) - -DEF_TRAVERSE_TYPE(InjectedClassNameType, {}) - -DEF_TRAVERSE_TYPE(AttributedType, - { TRY_TO(TraverseType(T->getModifiedType())); }) - -DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); }) - -DEF_TRAVERSE_TYPE(ElaboratedType, { - if (T->getQualifier()) { - TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); - } - TRY_TO(TraverseType(T->getNamedType())); -}) - -DEF_TRAVERSE_TYPE(DependentNameType, - { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); }) - -DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, { - TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); - TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); -}) - -DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); }) - -DEF_TRAVERSE_TYPE(ObjCInterfaceType, {}) - -DEF_TRAVERSE_TYPE(ObjCObjectType, { - // We have to watch out here because an ObjCInterfaceType's base - // type is itself. - if (T->getBaseType().getTypePtr() != T) - TRY_TO(TraverseType(T->getBaseType())); - for (auto typeArg : T->getTypeArgsAsWritten()) { - TRY_TO(TraverseType(typeArg)); - } -}) - -DEF_TRAVERSE_TYPE(ObjCObjectPointerType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); }) - -#undef DEF_TRAVERSE_TYPE - -// ----------------- TypeLoc traversal ----------------- - -// This macro makes available a variable TL, the passed-in TypeLoc. -// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc, -// in addition to WalkUpFrom* for the TypeLoc itself, such that existing -// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods -// continue to work. -#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \ - template \ - bool RecursiveASTVisitor::Traverse##TYPE##Loc(TYPE##Loc TL) { \ - if (getDerived().shouldWalkTypesOfTypeLocs()) \ - TRY_TO(WalkUpFrom##TYPE(const_cast(TL.getTypePtr()))); \ - TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ - { CODE; } \ - return true; \ - } - -template -bool -RecursiveASTVisitor::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) { - // Move this over to the 'main' typeloc tree. Note that this is a - // move -- we pretend that we were really looking at the unqualified - // typeloc all along -- rather than a recursion, so we don't follow - // the normal CRTP plan of going through - // getDerived().TraverseTypeLoc. If we did, we'd be traversing - // twice for the same type (once as a QualifiedTypeLoc version of - // the type, once as an UnqualifiedTypeLoc version of the type), - // which in effect means we'd call VisitTypeLoc twice with the - // 'same' type. This solves that problem, at the cost of never - // seeing the qualified version of the type (unless the client - // subclasses TraverseQualifiedTypeLoc themselves). It's not a - // perfect solution. A perfect solution probably requires making - // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a - // wrapper around Type* -- rather than being its own class in the - // type hierarchy. - return TraverseTypeLoc(TL.getUnqualifiedLoc()); -} - -DEF_TRAVERSE_TYPELOC(BuiltinType, {}) - -// FIXME: ComplexTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(ComplexType, { - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -DEF_TRAVERSE_TYPELOC(PointerType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(BlockPointerType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(LValueReferenceType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(RValueReferenceType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -// FIXME: location of base class? -// We traverse this in the type case as well, but how is it not reached through -// the pointee type? -DEF_TRAVERSE_TYPELOC(MemberPointerType, { - TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0))); - TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(AdjustedType, - { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); }) - -DEF_TRAVERSE_TYPELOC(DecayedType, - { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); }) - -template -bool RecursiveASTVisitor::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { - // This isn't available for ArrayType, but is for the ArrayTypeLoc. - TRY_TO(TraverseStmt(TL.getSizeExpr())); - return true; -} - -DEF_TRAVERSE_TYPELOC(ConstantArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -DEF_TRAVERSE_TYPELOC(VariableArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -// FIXME: order? why not size expr first? -// FIXME: base VectorTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, { - if (TL.getTypePtr()->getSizeExpr()) - TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr())); - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -// FIXME: VectorTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(VectorType, { - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -// FIXME: size and attributes -// FIXME: base VectorTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(ExtVectorType, { - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, - { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); }) - -// FIXME: location of exception specifications (attributes?) -DEF_TRAVERSE_TYPELOC(FunctionProtoType, { - TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); - - const FunctionProtoType *T = TL.getTypePtr(); - - for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) { - if (TL.getParam(I)) { - TRY_TO(TraverseDecl(TL.getParam(I))); - } else if (I < T->getNumParams()) { - TRY_TO(TraverseType(T->getParamType(I))); - } - } - - for (const auto &E : T->exceptions()) { - TRY_TO(TraverseType(E)); - } - - if (Expr *NE = T->getNoexceptExpr()) - TRY_TO(TraverseStmt(NE)); -}) - -DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {}) -DEF_TRAVERSE_TYPELOC(TypedefType, {}) - -DEF_TRAVERSE_TYPELOC(TypeOfExprType, - { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); }) - -DEF_TRAVERSE_TYPELOC(TypeOfType, { - TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); -}) - -// FIXME: location of underlying expr -DEF_TRAVERSE_TYPELOC(DecltypeType, { - TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); -}) - -DEF_TRAVERSE_TYPELOC(UnaryTransformType, { - TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(AutoType, { - TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); -}) - -DEF_TRAVERSE_TYPELOC(RecordType, {}) -DEF_TRAVERSE_TYPELOC(EnumType, {}) -DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {}) -DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {}) -DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {}) - -// FIXME: use the loc for the template name? -DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, { - TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName())); - for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { - TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); - } -}) - -DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {}) - -DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) - -DEF_TRAVERSE_TYPELOC(AttributedType, - { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) - -DEF_TRAVERSE_TYPELOC(ElaboratedType, { - if (TL.getQualifierLoc()) { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); - } - TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(DependentNameType, { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); -}) - -DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, { - if (TL.getQualifierLoc()) { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); - } - - for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { - TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); - } -}) - -DEF_TRAVERSE_TYPELOC(PackExpansionType, - { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); }) - -DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {}) - -DEF_TRAVERSE_TYPELOC(ObjCObjectType, { - // We have to watch out here because an ObjCInterfaceType's base - // type is itself. - if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr()) - TRY_TO(TraverseTypeLoc(TL.getBaseLoc())); - for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) - TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) - -#undef DEF_TRAVERSE_TYPELOC - -// ----------------- Decl traversal ----------------- -// -// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing -// the children that come from the DeclContext associated with it. -// Therefore each Traverse* only needs to worry about children other -// than those. - -template -bool RecursiveASTVisitor::TraverseDeclContextHelper(DeclContext *DC) { - if (!DC) - return true; - - for (auto *Child : DC->decls()) { - // BlockDecls and CapturedDecls are traversed through BlockExprs and - // CapturedStmts respectively. - if (!isa(Child) && !isa(Child)) - TRY_TO(TraverseDecl(Child)); - } - - return true; -} - -// This macro makes available a variable D, the passed-in decl. -#define DEF_TRAVERSE_DECL(DECL, CODE) \ - template \ - bool RecursiveASTVisitor::Traverse##DECL(DECL *D) { \ - TRY_TO(WalkUpFrom##DECL(D)); \ - { CODE; } \ - TRY_TO(TraverseDeclContextHelper(dyn_cast(D))); \ - return true; \ - } - -DEF_TRAVERSE_DECL(AccessSpecDecl, {}) - -DEF_TRAVERSE_DECL(BlockDecl, { - if (TypeSourceInfo *TInfo = D->getSignatureAsWritten()) - TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); - TRY_TO(TraverseStmt(D->getBody())); - for (const auto &I : D->captures()) { - if (I.hasCopyExpr()) { - 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; -}) - -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; -}) - -DEF_TRAVERSE_DECL(EmptyDecl, {}) - -DEF_TRAVERSE_DECL(FileScopeAsmDecl, - { TRY_TO(TraverseStmt(D->getAsmString())); }) - -DEF_TRAVERSE_DECL(ImportDecl, {}) - -DEF_TRAVERSE_DECL(FriendDecl, { - // Friend is either decl or a type. - if (D->getFriendType()) - TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); - else - TRY_TO(TraverseDecl(D->getFriendDecl())); -}) - -DEF_TRAVERSE_DECL(FriendTemplateDecl, { - if (D->getFriendType()) - TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); - else - TRY_TO(TraverseDecl(D->getFriendDecl())); - for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) { - TemplateParameterList *TPL = D->getTemplateParameterList(I); - for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end(); - ITPL != ETPL; ++ITPL) { - TRY_TO(TraverseDecl(*ITPL)); - } - } -}) - -DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, - { TRY_TO(TraverseDecl(D->getSpecialization())); }) - -DEF_TRAVERSE_DECL(LinkageSpecDecl, {}) - -DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this - }) - -DEF_TRAVERSE_DECL(StaticAssertDecl, { - TRY_TO(TraverseStmt(D->getAssertExpr())); - TRY_TO(TraverseStmt(D->getMessage())); -}) - -DEF_TRAVERSE_DECL( - TranslationUnitDecl, - {// Code in an unnamed namespace shows up automatically in - // decls_begin()/decls_end(). Thus we don't need to recurse on - // D->getAnonymousNamespace(). - }) - -DEF_TRAVERSE_DECL(ExternCContextDecl, {}) - -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; -}) - -DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl. - }) - -DEF_TRAVERSE_DECL( - NamespaceDecl, - {// Code in an unnamed namespace shows up automatically in - // decls_begin()/decls_end(). Thus we don't need to recurse on - // D->getAnonymousNamespace(). - }) - -DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement - }) - -DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement - if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) { - for (auto typeParam : *typeParamList) { - TRY_TO(TraverseObjCTypeParamDecl(typeParam)); - } - } - return true; -}) - -DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement - }) - -DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement - }) - -DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement - if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) { - for (auto typeParam : *typeParamList) { - TRY_TO(TraverseObjCTypeParamDecl(typeParam)); - } - } - - if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) { - TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc())); - } -}) - -DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement - }) - -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)); - } - if (D->isThisDeclarationADefinition()) { - TRY_TO(TraverseStmt(D->getBody())); - } - return true; -}) - -DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { - if (D->hasExplicitBound()) { - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - // We shouldn't traverse D->getTypeForDecl(); it's a result of - // declaring the type alias, not something that was written in the - // source. - } -}) - -DEF_TRAVERSE_DECL(ObjCPropertyDecl, { - if (D->getTypeSourceInfo()) - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - else - TRY_TO(TraverseType(D->getType())); - return true; -}) - -DEF_TRAVERSE_DECL(UsingDecl, { - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); -}) - -DEF_TRAVERSE_DECL(UsingDirectiveDecl, { - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); -}) - -DEF_TRAVERSE_DECL(UsingShadowDecl, {}) - -DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { - for (auto *I : D->varlists()) { - TRY_TO(TraverseStmt(I)); - } -}) - -// A helper method for TemplateDecl's children. -template -bool RecursiveASTVisitor::TraverseTemplateParameterListHelper( - TemplateParameterList *TPL) { - if (TPL) { - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - } - return true; -} - -// A helper method for traversing the implicit instantiations of a -// class template. -template -bool RecursiveASTVisitor::TraverseClassInstantiations( - ClassTemplateDecl *D) { - for (auto *SD : D->specializations()) { - for (auto *RD : SD->redecls()) { - // We don't want to visit injected-class-names in this traversal. - if (cast(RD)->isInjectedClassName()) - continue; - - switch ( - cast(RD)->getSpecializationKind()) { - // Visit the implicit instantiations with the requested pattern. - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - TRY_TO(TraverseDecl(RD)); - break; - - // We don't need to do anything on an explicit instantiation - // or explicit specialization because there will be an explicit - // node for it elsewhere. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - case TSK_ExplicitSpecialization: - break; - } - } - } - - return true; -} - -DEF_TRAVERSE_DECL(ClassTemplateDecl, { - CXXRecordDecl *TempDecl = D->getTemplatedDecl(); - TRY_TO(TraverseDecl(TempDecl)); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // class templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the class instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseClassInstantiations(D)); - - // Note that getInstantiatedFromMemberTemplate() is just a link - // from a template instantiation back to the template from which - // it was instantiated, and thus should not be traversed. -}) - -// A helper method for traversing the implicit instantiations of a -// class template. -template -bool RecursiveASTVisitor::TraverseVariableInstantiations( - VarTemplateDecl *D) { - for (auto *SD : D->specializations()) { - for (auto *RD : SD->redecls()) { - switch ( - cast(RD)->getSpecializationKind()) { - // Visit the implicit instantiations with the requested pattern. - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - TRY_TO(TraverseDecl(RD)); - break; - - // We don't need to do anything on an explicit instantiation - // or explicit specialization because there will be an explicit - // node for it elsewhere. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - case TSK_ExplicitSpecialization: - break; - } - } - } - - return true; -} - -DEF_TRAVERSE_DECL(VarTemplateDecl, { - VarDecl *TempDecl = D->getTemplatedDecl(); - TRY_TO(TraverseDecl(TempDecl)); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // variable templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the variable instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseVariableInstantiations(D)); - - // Note that getInstantiatedFromMemberTemplate() is just a link - // from a template instantiation back to the template from which - // it was instantiated, and thus should not be traversed. -}) - -// A helper method for traversing the instantiations of a -// function while skipping its specializations. -template -bool RecursiveASTVisitor::TraverseFunctionInstantiations( - FunctionTemplateDecl *D) { - for (auto *FD : D->specializations()) { - for (auto *RD : FD->redecls()) { - switch (RD->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - // We don't know what kind of FunctionDecl this is. - TRY_TO(TraverseDecl(RD)); - break; - - // No need to visit explicit instantiations, we'll find the node - // eventually. - // FIXME: This is incorrect; there is no other node for an explicit - // instantiation of a function template specialization. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - break; - - case TSK_ExplicitSpecialization: - break; - } - } - } - - return true; -} - -DEF_TRAVERSE_DECL(FunctionTemplateDecl, { - TRY_TO(TraverseDecl(D->getTemplatedDecl())); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // function templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the function instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseFunctionInstantiations(D)); -}) - -DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { - // D is the "T" in something like - // template