mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 09:41:03 -04:00
Vendor import of clang release_39 branch r276489:
https://llvm.org/svn/llvm-project/cfe/branches/release_39@276489
This commit is contained in:
parent
b4348ed0b7
commit
2b6b257f4e
3057 changed files with 291873 additions and 71050 deletions
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"project_id" : "clang",
|
||||
"conduit_uri" : "http://reviews.llvm.org/"
|
||||
"conduit_uri" : "https://reviews.llvm.org/"
|
||||
}
|
||||
|
|
|
|||
13
.clang-tidy
13
.clang-tidy
|
|
@ -1 +1,12 @@
|
|||
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*'
|
||||
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming'
|
||||
CheckOptions:
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.FunctionCase
|
||||
value: lowerCase
|
||||
- key: readability-identifier-naming.UnionCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.VariableCase
|
||||
value: CamelCase
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -33,3 +33,5 @@ tools/extra
|
|||
# Sphinx build products
|
||||
docs/_build
|
||||
docs/analyzer/_build
|
||||
# debug info testsuite
|
||||
test/debuginfo-tests
|
||||
|
|
|
|||
296
CMakeLists.txt
296
CMakeLists.txt
|
|
@ -1,18 +1,4 @@
|
|||
cmake_minimum_required(VERSION 2.8.8)
|
||||
|
||||
# FIXME: It may be removed when we use 2.8.12.
|
||||
if(CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
# Invalidate a couple of keywords.
|
||||
set(cmake_2_8_12_INTERFACE)
|
||||
set(cmake_2_8_12_PRIVATE)
|
||||
else()
|
||||
# Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries().
|
||||
set(cmake_2_8_12_INTERFACE INTERFACE)
|
||||
set(cmake_2_8_12_PRIVATE PRIVATE)
|
||||
if(POLICY CMP0022)
|
||||
cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
|
||||
endif()
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.4.3)
|
||||
|
||||
# If we are not building as a part of LLVM, build Clang as an
|
||||
# standalone project, using LLVM as an external library:
|
||||
|
|
@ -72,7 +58,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
|
|||
find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/share/llvm/cmake")
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
|
||||
set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
|
||||
if(EXISTS ${LLVMCONFIG_FILE})
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
|
||||
|
|
@ -101,6 +87,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
|
|||
include(AddLLVM)
|
||||
include(TableGen)
|
||||
include(HandleLLVMOptions)
|
||||
include(VersionFromVCS)
|
||||
|
||||
set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
|
||||
|
||||
|
|
@ -181,6 +168,10 @@ else()
|
|||
set(BACKEND_PACKAGE_STRING "${PACKAGE_STRING}")
|
||||
endif()
|
||||
|
||||
# Make sure that our source directory is on the current cmake module path so that
|
||||
# we can include cmake files from this directory.
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||
|
||||
find_package(LibXml2 2.5.3 QUIET)
|
||||
if (LIBXML2_FOUND)
|
||||
set(CLANG_HAVE_LIBXML 1)
|
||||
|
|
@ -196,10 +187,24 @@ set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." )
|
|||
set(DEFAULT_SYSROOT "" CACHE PATH
|
||||
"Default <path> to all compiler invocations for --sysroot=<path>." )
|
||||
|
||||
set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
|
||||
|
||||
set(ENABLE_X86_RELAX_RELOCATIONS OFF CACHE BOOL
|
||||
"enable x86 relax relocations by default")
|
||||
|
||||
set(CLANG_DEFAULT_CXX_STDLIB "" CACHE STRING
|
||||
"Default C++ stdlib to use (empty for architecture default, \"libstdc++\" or \"libc++\"")
|
||||
if (NOT(CLANG_DEFAULT_CXX_STDLIB STREQUAL "" OR
|
||||
CLANG_DEFAULT_CXX_STDLIB STREQUAL "libstdc++" OR
|
||||
CLANG_DEFAULT_CXX_STDLIB STREQUAL "libc++"))
|
||||
message(WARNING "Resetting default C++ stdlib to use architecture default")
|
||||
set(CLANG_DEFAULT_CXX_STDLIB "")
|
||||
endif()
|
||||
|
||||
set(CLANG_DEFAULT_OPENMP_RUNTIME "libomp" CACHE STRING
|
||||
"Default OpenMP runtime used by -fopenmp.")
|
||||
|
||||
set(CLANG_VENDOR "" CACHE STRING
|
||||
set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING
|
||||
"Vendor-specific text for showing with version information.")
|
||||
|
||||
if( CLANG_VENDOR )
|
||||
|
|
@ -307,134 +312,7 @@ configure_file(
|
|||
${CLANG_BINARY_DIR}/include/clang/Config/config.h)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
function(clang_tablegen)
|
||||
# Syntax:
|
||||
# clang_tablegen output-file [tablegen-arg ...] SOURCE source-file
|
||||
# [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]]
|
||||
#
|
||||
# Generates a custom command for invoking tblgen as
|
||||
#
|
||||
# tblgen source-file -o=output-file tablegen-arg ...
|
||||
#
|
||||
# and, if cmake-target-name is provided, creates a custom target for
|
||||
# executing the custom command depending on output-file. It is
|
||||
# possible to list more files to depend after DEPENDS.
|
||||
|
||||
cmake_parse_arguments(CTG "" "SOURCE;TARGET" "" ${ARGN})
|
||||
|
||||
if( NOT CTG_SOURCE )
|
||||
message(FATAL_ERROR "SOURCE source-file required by clang_tablegen")
|
||||
endif()
|
||||
|
||||
set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} )
|
||||
tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS})
|
||||
|
||||
if(CTG_TARGET)
|
||||
add_public_tablegen_target(${CTG_TARGET})
|
||||
set_target_properties( ${CTG_TARGET} PROPERTIES FOLDER "Clang tablegenning")
|
||||
set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET})
|
||||
endif()
|
||||
endfunction(clang_tablegen)
|
||||
|
||||
macro(set_clang_windows_version_resource_properties name)
|
||||
if(DEFINED windows_resource_file)
|
||||
set_windows_version_resource_properties(${name} ${windows_resource_file}
|
||||
VERSION_MAJOR ${CLANG_VERSION_MAJOR}
|
||||
VERSION_MINOR ${CLANG_VERSION_MINOR}
|
||||
VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL}
|
||||
VERSION_STRING "${CLANG_VERSION} (${BACKEND_PACKAGE_STRING})"
|
||||
PRODUCT_NAME "clang")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(add_clang_subdirectory name)
|
||||
add_llvm_subdirectory(CLANG TOOL ${name})
|
||||
endmacro()
|
||||
|
||||
macro(add_clang_library name)
|
||||
cmake_parse_arguments(ARG
|
||||
"SHARED"
|
||||
""
|
||||
"ADDITIONAL_HEADERS"
|
||||
${ARGN})
|
||||
set(srcs)
|
||||
if(MSVC_IDE OR XCODE)
|
||||
# Add public headers
|
||||
file(RELATIVE_PATH lib_path
|
||||
${CLANG_SOURCE_DIR}/lib/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
if(NOT lib_path MATCHES "^[.][.]")
|
||||
file( GLOB_RECURSE headers
|
||||
${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.h
|
||||
${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.def
|
||||
)
|
||||
set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
|
||||
file( GLOB_RECURSE tds
|
||||
${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.td
|
||||
)
|
||||
source_group("TableGen descriptions" FILES ${tds})
|
||||
set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
|
||||
if(headers OR tds)
|
||||
set(srcs ${headers} ${tds})
|
||||
endif()
|
||||
endif()
|
||||
endif(MSVC_IDE OR XCODE)
|
||||
if(srcs OR ARG_ADDITIONAL_HEADERS)
|
||||
set(srcs
|
||||
ADDITIONAL_HEADERS
|
||||
${srcs}
|
||||
${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args.
|
||||
)
|
||||
endif()
|
||||
if(ARG_SHARED)
|
||||
set(ARG_ENABLE_SHARED SHARED)
|
||||
endif()
|
||||
llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS} ${srcs})
|
||||
|
||||
if(TARGET ${name})
|
||||
target_link_libraries(${name} ${cmake_2_8_12_INTERFACE} ${LLVM_COMMON_LIBS})
|
||||
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
|
||||
install(TARGETS ${name}
|
||||
COMPONENT ${name}
|
||||
EXPORT ClangTargets
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
RUNTIME DESTINATION bin)
|
||||
|
||||
if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${name}
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${name}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name})
|
||||
else()
|
||||
# Add empty "phony" target
|
||||
add_custom_target(${name})
|
||||
endif()
|
||||
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Clang libraries")
|
||||
set_clang_windows_version_resource_properties(${name})
|
||||
endmacro(add_clang_library)
|
||||
|
||||
macro(add_clang_executable name)
|
||||
add_llvm_executable( ${name} ${ARGN} )
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Clang executables")
|
||||
set_clang_windows_version_resource_properties(${name})
|
||||
endmacro(add_clang_executable)
|
||||
|
||||
macro(add_clang_symlink name dest)
|
||||
add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE)
|
||||
# Always generate install targets
|
||||
llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE)
|
||||
endmacro()
|
||||
include(AddClang)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
|
|
@ -462,30 +340,11 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(INTERNAL_INSTALL_PREFIX)
|
||||
set(LIBCLANG_HEADERS_INSTALL_DESTINATION "${INTERNAL_INSTALL_PREFIX}/include")
|
||||
else()
|
||||
set(LIBCLANG_HEADERS_INSTALL_DESTINATION include)
|
||||
endif()
|
||||
|
||||
install(DIRECTORY include/clang-c
|
||||
COMPONENT libclang-headers
|
||||
DESTINATION "${LIBCLANG_HEADERS_INSTALL_DESTINATION}"
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's.
|
||||
add_custom_target(install-libclang-headers
|
||||
DEPENDS
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=libclang-headers
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
|
||||
add_definitions( -D_GNU_SOURCE )
|
||||
|
||||
option(CLANG_BUILD_TOOLS
|
||||
"Build the Clang tools. If OFF, just generate build targets." ON)
|
||||
|
||||
option(CLANG_ENABLE_ARCMT "Build ARCMT." ON)
|
||||
if (CLANG_ENABLE_ARCMT)
|
||||
set(ENABLE_CLANG_ARCMT "1")
|
||||
|
|
@ -579,51 +438,34 @@ if( CLANG_INCLUDE_DOCS )
|
|||
add_subdirectory(docs)
|
||||
endif()
|
||||
|
||||
set(CLANG_ORDER_FILE "" CACHE FILEPATH
|
||||
"Order file to use when compiling clang in order to improve startup time.")
|
||||
|
||||
if (CLANG_BUILT_STANDALONE OR CMAKE_VERSION VERSION_EQUAL 3 OR
|
||||
CMAKE_VERSION VERSION_GREATER 3)
|
||||
# Generate a list of CMake library targets so that other CMake projects can
|
||||
# link against them. LLVM calls its version of this file LLVMExports.cmake, but
|
||||
# the usual CMake convention seems to be ${Project}Targets.cmake.
|
||||
set(CLANG_INSTALL_PACKAGE_DIR share/clang/cmake)
|
||||
set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}")
|
||||
get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS)
|
||||
export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake)
|
||||
if(APPLE)
|
||||
# this line is needed as a cleanup to ensure that any CMakeCaches with the old
|
||||
# default value get updated to the new default.
|
||||
if(CLANG_ORDER_FILE STREQUAL "")
|
||||
unset(CLANG_ORDER_FILE CACHE)
|
||||
unset(CLANG_ORDER_FILE)
|
||||
endif()
|
||||
|
||||
# Install a <prefix>/share/clang/cmake/ClangConfig.cmake file so that
|
||||
# find_package(Clang) works. Install the target list with it.
|
||||
install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake
|
||||
DESTINATION share/clang/cmake)
|
||||
set(CLANG_ORDER_FILE ${CMAKE_CURRENT_BINARY_DIR}/clang.order CACHE FILEPATH
|
||||
"Order file to use when compiling clang in order to improve startup time (Darwin Only - requires ld64).")
|
||||
|
||||
# Also copy ClangConfig.cmake to the build directory so that dependent projects
|
||||
# can build against a build directory of Clang more easily.
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake
|
||||
${CLANG_BINARY_DIR}/share/clang/cmake/ClangConfig.cmake
|
||||
COPYONLY)
|
||||
endif ()
|
||||
if(CLANG_ORDER_FILE AND NOT EXISTS ${CLANG_ORDER_FILE})
|
||||
string(FIND "${CLANG_ORDER_FILE}" "${CMAKE_CURRENT_BINARY_DIR}" PATH_START)
|
||||
if(PATH_START EQUAL 0)
|
||||
file(WRITE ${CLANG_ORDER_FILE} "\n")
|
||||
else()
|
||||
message(FATAL_ERROR "Specified order file '${CLANG_ORDER_FILE}' does not exist.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(cmake/modules)
|
||||
|
||||
if (CLANG_ENABLE_BOOTSTRAP)
|
||||
include(ExternalProject)
|
||||
|
||||
if(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}")
|
||||
|
|
@ -649,14 +491,22 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
|
||||
set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-stamps/)
|
||||
set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-bins/)
|
||||
set(cmake_command ${CMAKE_COMMAND})
|
||||
|
||||
# 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)
|
||||
# If the next stage is LTO we need to depend on LTO and possibly LLVMgold
|
||||
if(BOOTSTRAP_LLVM_ENABLE_LTO OR LLVM_ENABLE_LTO)
|
||||
set(LTO_DEP LTO)
|
||||
if(APPLE)
|
||||
# on Darwin we need to set DARWIN_LTO_LIBRARY so that -flto will work
|
||||
# using the just-built compiler, and we need to override DYLD_LIBRARY_PATH
|
||||
# so that the host object file tools will use the just-built libLTO.
|
||||
set(LTO_LIBRARY -DDARWIN_LTO_LIBRARY=${LLVM_SHLIB_OUTPUT_INTDIR}/libLTO.dylib)
|
||||
set(cmake_command ${CMAKE_COMMAND} -E env DYLD_LIBRARY_PATH=${LLVM_LIBRARY_OUTPUT_INTDIR} ${CMAKE_COMMAND})
|
||||
elseif(NOT WIN32)
|
||||
list(APPEND LTO_DEP LLVMgold llvm-ar llvm-ranlib)
|
||||
set(LTO_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
|
||||
set(LTO_RANLIB -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(${NEXT_CLANG_STAGE}-clear
|
||||
|
|
@ -682,6 +532,7 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
LLVM_VERSION_MINOR
|
||||
LLVM_VERSION_PATCH
|
||||
LLVM_VERSION_SUFFIX
|
||||
LLVM_BINUTILS_INCDIR
|
||||
CLANG_REPOSITORY_STRING
|
||||
CMAKE_MAKE_PROGRAM)
|
||||
|
||||
|
|
@ -719,6 +570,10 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
list(APPEND PASSTHROUGH_VARIABLES
|
||||
-D${varName}=${value})
|
||||
endif()
|
||||
if(${variableName} AND variableName MATCHES "LLVM_EXTERNAL_.*_SOURCE_DIR")
|
||||
list(APPEND PASSTHROUGH_VARIABLES
|
||||
-D${variableName}=${${variableName}})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Populate the passthrough variables
|
||||
|
|
@ -736,7 +591,7 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
SOURCE_DIR ${CMAKE_SOURCE_DIR}
|
||||
STAMP_DIR ${STAMP_DIR}
|
||||
BINARY_DIR ${BINARY_DIR}
|
||||
${cmake_3_1_EXCLUDE_FROM_ALL}
|
||||
EXCLUDE_FROM_ALL 1
|
||||
CMAKE_ARGS
|
||||
# We shouldn't need to set this here, but INSTALL_DIR doesn't
|
||||
# seem to work, so instead I'm passing this through
|
||||
|
|
@ -746,18 +601,21 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
-DCLANG_STAGE=${NEXT_CLANG_STAGE}
|
||||
${COMPILER_OPTIONS}
|
||||
${LTO_LIBRARY} ${LTO_AR} ${LTO_RANLIB} ${verbose} ${PGO_OPT}
|
||||
CMAKE_COMMAND ${cmake_command}
|
||||
INSTALL_COMMAND ""
|
||||
STEP_TARGETS configure build
|
||||
${cmake_3_4_USES_TERMINAL_OPTIONS}
|
||||
USES_TERMINAL_CONFIGURE 1
|
||||
USES_TERMINAL_BUILD 1
|
||||
USES_TERMINAL_INSTALL 1
|
||||
)
|
||||
|
||||
# exclude really-install from main target
|
||||
set_target_properties(${NEXT_CLANG_STAGE} PROPERTIES _EP_really-install_EXCLUDE_FROM_MAIN On)
|
||||
ExternalProject_Add_Step(${NEXT_CLANG_STAGE} really-install
|
||||
COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target install
|
||||
COMMAND ${cmake_command} --build <BINARY_DIR> --target install
|
||||
COMMENT "Performing install step for '${NEXT_CLANG_STAGE}'"
|
||||
DEPENDEES build
|
||||
${cmake_3_4_USES_TERMINAL}
|
||||
USES_TERMINAL 1
|
||||
)
|
||||
ExternalProject_Add_StepTargets(${NEXT_CLANG_STAGE} really-install)
|
||||
add_custom_target(${NEXT_CLANG_STAGE}-install DEPENDS ${NEXT_CLANG_STAGE}-really-install)
|
||||
|
|
@ -770,10 +628,10 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
set_target_properties(${NEXT_CLANG_STAGE} PROPERTIES _EP_${target}_EXCLUDE_FROM_MAIN On)
|
||||
|
||||
ExternalProject_Add_Step(${NEXT_CLANG_STAGE} ${target}
|
||||
COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target ${target}
|
||||
COMMAND ${cmake_command} --build <BINARY_DIR> --target ${target}
|
||||
COMMENT "Performing ${target} for '${NEXT_CLANG_STAGE}'"
|
||||
DEPENDEES configure
|
||||
${cmake_3_4_USES_TERMINAL}
|
||||
USES_TERMINAL 1
|
||||
)
|
||||
|
||||
if(target MATCHES "^stage[0-9]*")
|
||||
|
|
@ -783,3 +641,7 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
|||
ExternalProject_Add_StepTargets(${NEXT_CLANG_STAGE} ${target})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION)
|
||||
add_subdirectory(utils/ClangVisualizers)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ D: CMake, library layering
|
|||
|
||||
N: Eric Christopher
|
||||
E: echristo@gmail.com
|
||||
D: Debug Information, autotools/configure/make build, inline assembly
|
||||
D: Debug Information, inline assembly
|
||||
|
||||
N: Doug Gregor
|
||||
E: dgregor@apple.com
|
||||
|
|
@ -52,3 +52,7 @@ D: Clang LLVM IR generation
|
|||
N: Richard Smith
|
||||
E: richard@metafoo.co.uk
|
||||
D: All parts of Clang not covered by someone else
|
||||
|
||||
N: Anastasia Stulova
|
||||
E: anastasia.stulova@arm.com
|
||||
D: OpenCL support
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ LLVM Release License
|
|||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2007-2015 University of Illinois at Urbana-Champaign.
|
||||
Copyright (c) 2007-2016 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
|
|
|||
124
Makefile
124
Makefile
|
|
@ -1,124 +0,0 @@
|
|||
##===- Makefile --------------------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
# If CLANG_LEVEL is not set, then we are the top-level Makefile. Otherwise, we
|
||||
# are being included from a subdirectory makefile.
|
||||
|
||||
ifndef CLANG_LEVEL
|
||||
|
||||
IS_TOP_LEVEL := 1
|
||||
CLANG_LEVEL := .
|
||||
DIRS := utils/TableGen include lib tools runtime docs unittests
|
||||
|
||||
PARALLEL_DIRS :=
|
||||
|
||||
ifeq ($(BUILD_EXAMPLES),1)
|
||||
PARALLEL_DIRS += examples
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_EXAMPLES),1)
|
||||
ENABLE_CLANG_EXAMPLES := 1
|
||||
else
|
||||
ENABLE_CLANG_EXAMPLES := 0
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),libs-only)
|
||||
DIRS := $(filter-out tools docs, $(DIRS))
|
||||
OPTIONAL_DIRS :=
|
||||
endif
|
||||
ifeq ($(BUILD_CLANG_ONLY),YES)
|
||||
DIRS := $(filter-out docs unittests, $(DIRS))
|
||||
OPTIONAL_DIRS :=
|
||||
endif
|
||||
|
||||
###
|
||||
# Common Makefile code, shared by all Clang Makefiles.
|
||||
|
||||
# Set LLVM source root level.
|
||||
LEVEL := $(CLANG_LEVEL)/../..
|
||||
|
||||
# Include LLVM common makefile.
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
ifneq ($(ENABLE_DOCS),1)
|
||||
DIRS := $(filter-out docs, $(DIRS))
|
||||
endif
|
||||
|
||||
# Set common Clang build flags.
|
||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include -I$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include
|
||||
ifdef CLANG_VENDOR
|
||||
CPP.Flags += -DCLANG_VENDOR='"$(CLANG_VENDOR) "'
|
||||
endif
|
||||
ifdef CLANG_REPOSITORY_STRING
|
||||
CPP.Flags += -DCLANG_REPOSITORY_STRING='"$(CLANG_REPOSITORY_STRING)"'
|
||||
endif
|
||||
|
||||
# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't
|
||||
# work with it enabled with GCC), Clang/llvm-gcc don't support it yet, and newer
|
||||
# GCC's have false positive warnings with it on Linux (which prove a pain to
|
||||
# fix). For example:
|
||||
# http://gcc.gnu.org/PR41874
|
||||
# http://gcc.gnu.org/PR41838
|
||||
#
|
||||
# We don't need to do this if the host compiler is clang.
|
||||
ifneq ($(CXX_COMPILER), "clang")
|
||||
CXX.Flags += -fno-strict-aliasing
|
||||
endif
|
||||
|
||||
|
||||
# Set up Clang's tblgen.
|
||||
ifndef CLANG_TBLGEN
|
||||
ifeq ($(LLVM_CROSS_COMPILING),1)
|
||||
CLANG_TBLGEN := $(BuildLLVMToolDir)/clang-tblgen$(BUILD_EXEEXT)
|
||||
else
|
||||
CLANG_TBLGEN := $(LLVMToolDir)/clang-tblgen$(EXEEXT)
|
||||
endif
|
||||
endif
|
||||
ClangTableGen = $(CLANG_TBLGEN) $(TableGen.Flags)
|
||||
|
||||
###
|
||||
# Clang Top Level specific stuff.
|
||||
|
||||
ifeq ($(IS_TOP_LEVEL),1)
|
||||
|
||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
$(RecursiveTargets)::
|
||||
$(Verb) for dir in test unittests; do \
|
||||
if [ -f $(PROJ_SRC_DIR)/$${dir}/Makefile ] && [ ! -f $${dir}/Makefile ]; then \
|
||||
$(MKDIR) $${dir}; \
|
||||
$(CP) $(PROJ_SRC_DIR)/$${dir}/Makefile $${dir}/Makefile; \
|
||||
fi \
|
||||
done
|
||||
endif
|
||||
|
||||
test::
|
||||
@ $(MAKE) -C test
|
||||
|
||||
report::
|
||||
@ $(MAKE) -C test report
|
||||
|
||||
clean::
|
||||
@ $(MAKE) -C test clean
|
||||
|
||||
libs-only: all
|
||||
|
||||
tags::
|
||||
$(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \
|
||||
grep -v /lib/Headers | grep -v /test/`
|
||||
|
||||
cscope.files:
|
||||
find tools lib include -name '*.cpp' \
|
||||
-or -name '*.def' \
|
||||
-or -name '*.td' \
|
||||
-or -name '*.h' > cscope.files
|
||||
|
||||
.PHONY: test report clean cscope.files
|
||||
|
||||
endif
|
||||
|
|
@ -359,6 +359,23 @@ class Diagnostic(object):
|
|||
|
||||
return FixItIterator(self)
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
class ChildDiagnosticsIterator:
|
||||
def __init__(self, diag):
|
||||
self.diag_set = conf.lib.clang_getChildDiagnostics(diag)
|
||||
|
||||
def __len__(self):
|
||||
return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set))
|
||||
|
||||
def __getitem__(self, key):
|
||||
diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key)
|
||||
if not diag:
|
||||
raise IndexError
|
||||
return Diagnostic(diag)
|
||||
|
||||
return ChildDiagnosticsIterator(self)
|
||||
|
||||
@property
|
||||
def category_number(self):
|
||||
"""The category number for this diagnostic or 0 if unavailable."""
|
||||
|
|
@ -1120,6 +1137,9 @@ CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
|
|||
# A type alias template declaration
|
||||
CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601)
|
||||
|
||||
# A code completion overload candidate.
|
||||
CursorKind.OVERLOAD_CANDIDATE = CursorKind(700)
|
||||
|
||||
### Template Argument Kinds ###
|
||||
class TemplateArgumentKind(BaseEnumeration):
|
||||
"""
|
||||
|
|
@ -1174,6 +1194,32 @@ class Cursor(Structure):
|
|||
"""
|
||||
return conf.lib.clang_CXXMethod_isConst(self)
|
||||
|
||||
def is_converting_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ converting constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isConvertingConstructor(self)
|
||||
|
||||
def is_copy_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ copy constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isCopyConstructor(self)
|
||||
|
||||
def is_default_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ default constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isDefaultConstructor(self)
|
||||
|
||||
def is_move_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ move constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isMoveConstructor(self)
|
||||
|
||||
def is_default_method(self):
|
||||
"""Returns True if the cursor refers to a C++ member function or member
|
||||
function template that is declared '= default'.
|
||||
"""
|
||||
return conf.lib.clang_CXXMethod_isDefaulted(self)
|
||||
|
||||
def is_mutable_field(self):
|
||||
"""Returns True if the cursor refers to a C++ field that is declared
|
||||
'mutable'.
|
||||
|
|
@ -1685,6 +1731,7 @@ TypeKind.DEPENDENT = TypeKind(26)
|
|||
TypeKind.OBJCID = TypeKind(27)
|
||||
TypeKind.OBJCCLASS = TypeKind(28)
|
||||
TypeKind.OBJCSEL = TypeKind(29)
|
||||
TypeKind.FLOAT128 = TypeKind(30)
|
||||
TypeKind.COMPLEX = TypeKind(100)
|
||||
TypeKind.POINTER = TypeKind(101)
|
||||
TypeKind.BLOCKPOINTER = TypeKind(102)
|
||||
|
|
@ -1704,6 +1751,7 @@ TypeKind.VARIABLEARRAY = TypeKind(115)
|
|||
TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
|
||||
TypeKind.MEMBERPOINTER = TypeKind(117)
|
||||
TypeKind.AUTO = TypeKind(118)
|
||||
TypeKind.ELABORATED = TypeKind(119)
|
||||
|
||||
class RefQualifierKind(BaseEnumeration):
|
||||
"""Describes a specific ref-qualifier of a type."""
|
||||
|
|
@ -1902,6 +1950,12 @@ class Type(Structure):
|
|||
"""
|
||||
return conf.lib.clang_Type_getClassType(self)
|
||||
|
||||
def get_named_type(self):
|
||||
"""
|
||||
Retrieve the type named by the qualified-id.
|
||||
"""
|
||||
return conf.lib.clang_Type_getNamedType(self)
|
||||
|
||||
def get_align(self):
|
||||
"""
|
||||
Retrieve the alignment of the record.
|
||||
|
|
@ -2383,7 +2437,7 @@ class TranslationUnit(ClangObject):
|
|||
functions above. __init__ is only called internally.
|
||||
"""
|
||||
assert isinstance(index, Index)
|
||||
|
||||
self.index = index
|
||||
ClangObject.__init__(self, ptr)
|
||||
|
||||
def __del__(self):
|
||||
|
|
@ -2702,6 +2756,11 @@ class CompileCommand(object):
|
|||
"""Get the working directory for this CompileCommand"""
|
||||
return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
"""Get the working filename for this CompileCommand"""
|
||||
return conf.lib.clang_CompileCommand_getFilename(self.cmd)
|
||||
|
||||
@property
|
||||
def arguments(self):
|
||||
"""
|
||||
|
|
@ -2884,6 +2943,11 @@ functionList = [
|
|||
_CXString,
|
||||
_CXString.from_result),
|
||||
|
||||
("clang_CompileCommand_getFilename",
|
||||
[c_object_p],
|
||||
_CXString,
|
||||
_CXString.from_result),
|
||||
|
||||
("clang_CompileCommand_getNumArgs",
|
||||
[c_object_p],
|
||||
c_uint),
|
||||
|
|
@ -2908,6 +2972,22 @@ functionList = [
|
|||
[Index, c_char_p],
|
||||
c_object_p),
|
||||
|
||||
("clang_CXXConstructor_isConvertingConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXConstructor_isCopyConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXConstructor_isDefaultConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXConstructor_isMoveConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXField_isMutable",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
|
@ -2916,6 +2996,10 @@ functionList = [
|
|||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXMethod_isDefaulted",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXMethod_isPureVirtual",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
|
@ -2997,6 +3081,10 @@ functionList = [
|
|||
Type,
|
||||
Type.from_result),
|
||||
|
||||
("clang_getChildDiagnostics",
|
||||
[Diagnostic],
|
||||
c_object_p),
|
||||
|
||||
("clang_getCompletionAvailability",
|
||||
[c_void_p],
|
||||
c_int),
|
||||
|
|
@ -3117,6 +3205,10 @@ functionList = [
|
|||
_CXString,
|
||||
_CXString.from_result),
|
||||
|
||||
("clang_getDiagnosticInSet",
|
||||
[c_object_p, c_uint],
|
||||
c_object_p),
|
||||
|
||||
("clang_getDiagnosticLocation",
|
||||
[Diagnostic],
|
||||
SourceLocation),
|
||||
|
|
@ -3218,6 +3310,10 @@ functionList = [
|
|||
[c_object_p],
|
||||
c_uint),
|
||||
|
||||
("clang_getNumDiagnosticsInSet",
|
||||
[c_object_p],
|
||||
c_uint),
|
||||
|
||||
("clang_getNumElements",
|
||||
[Type],
|
||||
c_longlong),
|
||||
|
|
@ -3477,6 +3573,11 @@ functionList = [
|
|||
[Type],
|
||||
c_uint),
|
||||
|
||||
("clang_Type_getNamedType",
|
||||
[Type],
|
||||
Type,
|
||||
Type.from_result),
|
||||
|
||||
("clang_Type_visitFields",
|
||||
[Type, callbacks['fields_visit'], py_object],
|
||||
c_uint),
|
||||
|
|
|
|||
|
|
@ -38,27 +38,34 @@ def test_all_compilecommand():
|
|||
cmds = cdb.getAllCompileCommands()
|
||||
assert len(cmds) == 3
|
||||
expected = [
|
||||
{ 'wd': '/home/john.doe/MyProject',
|
||||
'file': '/home/john.doe/MyProject/project.cpp',
|
||||
'line': ['clang++', '-o', 'project.o', '-c',
|
||||
'/home/john.doe/MyProject/project.cpp']},
|
||||
{ 'wd': '/home/john.doe/MyProjectA',
|
||||
'file': '/home/john.doe/MyProject/project2.cpp',
|
||||
'line': ['clang++', '-o', 'project2.o', '-c',
|
||||
'/home/john.doe/MyProject/project2.cpp']},
|
||||
{ 'wd': '/home/john.doe/MyProjectB',
|
||||
'file': '/home/john.doe/MyProject/project2.cpp',
|
||||
'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c',
|
||||
'/home/john.doe/MyProject/project2.cpp']},
|
||||
{ 'wd': '/home/john.doe/MyProject',
|
||||
'line': ['clang++', '-o', 'project.o', '-c',
|
||||
'/home/john.doe/MyProject/project.cpp']}
|
||||
|
||||
]
|
||||
for i in range(len(cmds)):
|
||||
assert cmds[i].directory == expected[i]['wd']
|
||||
assert cmds[i].filename == expected[i]['file']
|
||||
for arg, exp in zip(cmds[i].arguments, expected[i]['line']):
|
||||
assert arg == exp
|
||||
|
||||
def test_1_compilecommand():
|
||||
"""Check file with single compile command"""
|
||||
cdb = CompilationDatabase.fromDirectory(kInputsDir)
|
||||
cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
|
||||
file = '/home/john.doe/MyProject/project.cpp'
|
||||
cmds = cdb.getCompileCommands(file)
|
||||
assert len(cmds) == 1
|
||||
assert cmds[0].directory == '/home/john.doe/MyProject'
|
||||
assert cmds[0].directory == os.path.dirname(file)
|
||||
assert cmds[0].filename == file
|
||||
expected = [ 'clang++', '-o', 'project.o', '-c',
|
||||
'/home/john.doe/MyProject/project.cpp']
|
||||
for arg, exp in zip(cmds[0].arguments, expected):
|
||||
|
|
|
|||
|
|
@ -112,6 +112,88 @@ def test_is_const_method():
|
|||
assert foo.is_const_method()
|
||||
assert not bar.is_const_method()
|
||||
|
||||
def test_is_converting_constructor():
|
||||
"""Ensure Cursor.is_converting_constructor works."""
|
||||
source = 'class X { explicit X(int); X(double); X(); };'
|
||||
tu = get_tu(source, lang='cpp')
|
||||
|
||||
xs = get_cursors(tu, 'X')
|
||||
|
||||
assert len(xs) == 4
|
||||
assert xs[0].kind == CursorKind.CLASS_DECL
|
||||
cs = xs[1:]
|
||||
assert cs[0].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[1].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[2].kind == CursorKind.CONSTRUCTOR
|
||||
|
||||
assert not cs[0].is_converting_constructor()
|
||||
assert cs[1].is_converting_constructor()
|
||||
assert not cs[2].is_converting_constructor()
|
||||
|
||||
|
||||
def test_is_copy_constructor():
|
||||
"""Ensure Cursor.is_copy_constructor works."""
|
||||
source = 'class X { X(); X(const X&); X(X&&); };'
|
||||
tu = get_tu(source, lang='cpp')
|
||||
|
||||
xs = get_cursors(tu, 'X')
|
||||
assert xs[0].kind == CursorKind.CLASS_DECL
|
||||
cs = xs[1:]
|
||||
assert cs[0].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[1].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[2].kind == CursorKind.CONSTRUCTOR
|
||||
|
||||
assert not cs[0].is_copy_constructor()
|
||||
assert cs[1].is_copy_constructor()
|
||||
assert not cs[2].is_copy_constructor()
|
||||
|
||||
def test_is_default_constructor():
|
||||
"""Ensure Cursor.is_default_constructor works."""
|
||||
source = 'class X { X(); X(int); };'
|
||||
tu = get_tu(source, lang='cpp')
|
||||
|
||||
xs = get_cursors(tu, 'X')
|
||||
assert xs[0].kind == CursorKind.CLASS_DECL
|
||||
cs = xs[1:]
|
||||
assert cs[0].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[1].kind == CursorKind.CONSTRUCTOR
|
||||
|
||||
assert cs[0].is_default_constructor()
|
||||
assert not cs[1].is_default_constructor()
|
||||
|
||||
def test_is_move_constructor():
|
||||
"""Ensure Cursor.is_move_constructor works."""
|
||||
source = 'class X { X(); X(const X&); X(X&&); };'
|
||||
tu = get_tu(source, lang='cpp')
|
||||
|
||||
xs = get_cursors(tu, 'X')
|
||||
assert xs[0].kind == CursorKind.CLASS_DECL
|
||||
cs = xs[1:]
|
||||
assert cs[0].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[1].kind == CursorKind.CONSTRUCTOR
|
||||
assert cs[2].kind == CursorKind.CONSTRUCTOR
|
||||
|
||||
assert not cs[0].is_move_constructor()
|
||||
assert not cs[1].is_move_constructor()
|
||||
assert cs[2].is_move_constructor()
|
||||
|
||||
def test_is_default_method():
|
||||
"""Ensure Cursor.is_default_method works."""
|
||||
source = 'class X { X() = default; }; class Y { Y(); };'
|
||||
tu = get_tu(source, lang='cpp')
|
||||
|
||||
xs = get_cursors(tu, 'X')
|
||||
ys = get_cursors(tu, 'Y')
|
||||
|
||||
assert len(xs) == 2
|
||||
assert len(ys) == 2
|
||||
|
||||
xc = xs[1]
|
||||
yc = ys[1]
|
||||
|
||||
assert xc.is_default_method()
|
||||
assert not yc.is_default_method()
|
||||
|
||||
def test_is_mutable_field():
|
||||
"""Ensure Cursor.is_mutable_field works."""
|
||||
source = 'class X { int x_; mutable int y_; };'
|
||||
|
|
|
|||
|
|
@ -80,3 +80,15 @@ def test_diagnostic_option():
|
|||
|
||||
assert d.option == '-Wunused-parameter'
|
||||
assert d.disable_option == '-Wno-unused-parameter'
|
||||
|
||||
def test_diagnostic_children():
|
||||
tu = get_tu('void f(int x) {} void g() { f(); }')
|
||||
assert len(tu.diagnostics) == 1
|
||||
d = tu.diagnostics[0]
|
||||
|
||||
children = d.children
|
||||
assert len(children) == 1
|
||||
assert children[0].severity == Diagnostic.Note
|
||||
assert children[0].spelling.endswith('declared here')
|
||||
assert children[0].location.line == 1
|
||||
assert children[0].location.column == 1
|
||||
|
|
|
|||
15
cmake/caches/3-stage-base.cmake
Normal file
15
cmake/caches/3-stage-base.cmake
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "")
|
||||
set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")
|
||||
set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "")
|
||||
set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "")
|
||||
|
||||
set(CLANG_BOOTSTRAP_TARGETS
|
||||
clang
|
||||
check-all
|
||||
check-llvm
|
||||
check-clang
|
||||
test-suite CACHE STRING "")
|
||||
|
||||
set(CLANG_BOOTSTRAP_CMAKE_ARGS
|
||||
-C ${CMAKE_CURRENT_LIST_DIR}/3-stage-base.cmake
|
||||
CACHE STRING "")
|
||||
16
cmake/caches/3-stage.cmake
Normal file
16
cmake/caches/3-stage.cmake
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
set(CLANG_BOOTSTRAP_TARGETS
|
||||
clang
|
||||
check-all
|
||||
check-llvm
|
||||
check-clang
|
||||
test-suite
|
||||
stage3
|
||||
stage3-clang
|
||||
stage3-check-all
|
||||
stage3-check-llvm
|
||||
stage3-check-clang
|
||||
stage3-test-suite CACHE STRING "")
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/3-stage-base.cmake)
|
||||
|
|
@ -16,15 +16,36 @@ set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
|
|||
set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "")
|
||||
set(CMAKE_MACOSX_RPATH ON CACHE BOOL "")
|
||||
set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "")
|
||||
set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
|
||||
set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
|
||||
set(CLANG_BOOTSTRAP_PASSTHROUGH
|
||||
CMAKE_OSX_ARCHITECTURES
|
||||
CACHE STRING "")
|
||||
|
||||
set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "")
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
|
||||
set(PACKAGE_VERSION 7.1.0 CACHE STRING "")
|
||||
|
||||
# LIBCXX Settings
|
||||
set(LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "")
|
||||
set(LIBCXX_INSTALL_HEADERS ON CACHE BOOL "")
|
||||
set(LIBCXX_OVERRIDE_DARWIN_INSTALL ON CACHE BOOL "")
|
||||
|
||||
set(CLANG_BOOTSTRAP_TARGETS
|
||||
generate-order-file
|
||||
check-all
|
||||
check-llvm
|
||||
check-clang
|
||||
llvm-config
|
||||
test-suite
|
||||
test-depends
|
||||
llvm-test-depends
|
||||
clang-test-depends
|
||||
distribution
|
||||
install-distribution
|
||||
clang CACHE STRING "")
|
||||
|
||||
#bootstrap
|
||||
set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")
|
||||
set(CLANG_BOOTSTRAP_CMAKE_ARGS
|
||||
|
|
|
|||
|
|
@ -2,23 +2,37 @@
|
|||
# specified by the stage1 build.
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD X86 ARM AArch64 CACHE STRING "")
|
||||
set(CLANG_VENDOR Apple CACHE STRING "")
|
||||
set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(PACKAGE_VENDOR Apple CACHE STRING "")
|
||||
set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
|
||||
set(LLVM_INCLUDE_UTILS OFF CACHE BOOL "")
|
||||
set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
|
||||
set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "")
|
||||
set(LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD OFF CACHE BOOL "")
|
||||
set(CLANG_TOOL_SCAN_BUILD_BUILD OFF CACHE BOOL "")
|
||||
set(CLANG_TOOL_SCAN_VIEW_BUILD OFF CACHE BOOL "")
|
||||
set(CLANG_LINKS_TO_CREATE clang++ cc c++ CACHE STRING "")
|
||||
set(CMAKE_MACOSX_RPATH ON CACHE BOOL "")
|
||||
set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
|
||||
set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
|
||||
set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
|
||||
set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
|
||||
set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -flto -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -flto -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "Build Compiler-RT with just-built clang")
|
||||
set(COMPILER_RT_ENABLE_IOS ON CACHE BOOL "Build iOS Compiler-RT libraries")
|
||||
|
||||
# Make unit tests (if present) part of the ALL target
|
||||
set(LLVM_BUILD_TESTS ON CACHE BOOL "")
|
||||
|
||||
set(LLVM_ENABLE_LTO ON CACHE BOOL "")
|
||||
set(CMAKE_C_FLAGS "-fno-stack-protector -fno-common -Wno-profile-instr-unprofiled" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS "-fno-stack-protector -fno-common -Wno-profile-instr-unprofiled" CACHE STRING "")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
|
||||
set(PACKAGE_VERSION 7.1.0 CACHE STRING "")
|
||||
|
||||
set(LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "")
|
||||
set(LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "")
|
||||
set(LIBCXX_INSTALL_HEADERS ON CACHE BOOL "")
|
||||
set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "")
|
||||
set(LLVM_LTO_VERSION_OFFSET 3000 CACHE STRING "")
|
||||
|
||||
# setup toolchain
|
||||
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
|
||||
|
|
@ -27,4 +41,20 @@ set(LLVM_TOOLCHAIN_TOOLS
|
|||
llvm-cov
|
||||
llvm-dwarfdump
|
||||
llvm-profdata
|
||||
llvm-objdump
|
||||
llvm-nm
|
||||
llvm-size
|
||||
CACHE STRING "")
|
||||
|
||||
set(LLVM_DISTRIBUTION_COMPONENTS
|
||||
clang
|
||||
LTO
|
||||
clang-format
|
||||
clang-headers
|
||||
libcxx-headers
|
||||
${LLVM_TOOLCHAIN_TOOLS}
|
||||
CACHE STRING "")
|
||||
|
||||
# test args
|
||||
|
||||
set(LLVM_LIT_ARGS "--xunit-xml-output=testresults.xunit.xml -v" CACHE STRING "")
|
||||
|
|
|
|||
|
|
@ -4,15 +4,71 @@ CMake Caches
|
|||
This directory contains CMake cache scripts that pre-populate the CMakeCache in
|
||||
a build directory with commonly used settings.
|
||||
|
||||
The first two cache files in the directory are used by Apple to build the clang
|
||||
distribution packaged with Xcode. You can use the caches with the following
|
||||
CMake invocation:
|
||||
You can use the caches files with the following CMake invocation:
|
||||
|
||||
cmake -G <build system>
|
||||
-C <path to llvm>/tools/clang/cmake/caches/Apple-stage1.cmake
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
[-DCMAKE_INSTALL_PREFIX=<install path>]
|
||||
-C <path to cache file>
|
||||
[additional CMake options (i.e. -DCMAKE_INSTALL_PREFIX=<install path>)]
|
||||
<path to llvm>
|
||||
|
||||
Building the `bootstrap` target from this generation will build clang, and
|
||||
`bootstrap-install` will install it.
|
||||
Options specified on the command line will override options in the cache files.
|
||||
|
||||
The following cache files exist.
|
||||
|
||||
Apple-stage1
|
||||
------------
|
||||
|
||||
The Apple stage1 cache configures a two stage build similar to how Apple builds
|
||||
the clang shipped with Xcode. The build files generated from this invocation has
|
||||
a target named "stage2" which performs an LTO build of clang.
|
||||
|
||||
The Apple-stage2 cache can be used directly to match the build settings Apple
|
||||
uses in shipping builds without doing a full bootstrap build.
|
||||
|
||||
PGO
|
||||
---
|
||||
|
||||
The PGO CMake cache can be used to generate a multi-stage instrumented compiler.
|
||||
You can configure your build directory with the following invocation of CMake:
|
||||
|
||||
cmake -G <generator> -C <path_to_clang>/cmake/caches/PGO.cmake <source dir>
|
||||
|
||||
After configuration the following additional targets will be generated:
|
||||
|
||||
stage2-instrumented:
|
||||
Builds a stage1 x86 compiler, runtime, and required tools (llvm-config,
|
||||
llvm-profdata) then uses that compiler to build an instrumented stage2 compiler.
|
||||
|
||||
stage2-instrumented-generate-profdata:
|
||||
Depends on "stage2-instrumented" and will use the instrumented compiler to
|
||||
generate profdata based on the training files in <clang>/utils/perf-training
|
||||
|
||||
stage2:
|
||||
Depends on "stage2-instrumented-generate-profdata" and will use the stage1
|
||||
compiler with the stage2 profdata to build a PGO-optimized compiler.
|
||||
|
||||
stage2-check-llvm:
|
||||
Depends on stage2 and runs check-llvm using the stage3 compiler.
|
||||
|
||||
stage2-check-clang:
|
||||
Depends on stage2 and runs check-clang using the stage3 compiler.
|
||||
|
||||
stage2-check-all:
|
||||
Depends on stage2 and runs check-all using the stage3 compiler.
|
||||
|
||||
stage2-test-suite:
|
||||
Depends on stage2 and runs the test-suite using the stage3 compiler (requires
|
||||
in-tree test-suite).
|
||||
|
||||
3-stage
|
||||
-------
|
||||
|
||||
This cache file can be used to generate a 3-stage clang build. You can configure
|
||||
using the following CMake command:
|
||||
|
||||
cmake -C <path to clang>/cmake/caches/3-stage.cmake -G Ninja <path to llvm>
|
||||
|
||||
You can then run "ninja stage3-clang" to build stage1, stage2 and stage3 clangs.
|
||||
|
||||
This is useful for finding non-determinism the compiler by verifying that stage2
|
||||
and stage3 are identical.
|
||||
|
|
|
|||
149
cmake/modules/AddClang.cmake
Normal file
149
cmake/modules/AddClang.cmake
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
function(clang_tablegen)
|
||||
# Syntax:
|
||||
# clang_tablegen output-file [tablegen-arg ...] SOURCE source-file
|
||||
# [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]]
|
||||
#
|
||||
# Generates a custom command for invoking tblgen as
|
||||
#
|
||||
# tblgen source-file -o=output-file tablegen-arg ...
|
||||
#
|
||||
# and, if cmake-target-name is provided, creates a custom target for
|
||||
# executing the custom command depending on output-file. It is
|
||||
# possible to list more files to depend after DEPENDS.
|
||||
|
||||
cmake_parse_arguments(CTG "" "SOURCE;TARGET" "" ${ARGN})
|
||||
|
||||
if( NOT CTG_SOURCE )
|
||||
message(FATAL_ERROR "SOURCE source-file required by clang_tablegen")
|
||||
endif()
|
||||
|
||||
set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} )
|
||||
tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS})
|
||||
|
||||
if(CTG_TARGET)
|
||||
add_public_tablegen_target(${CTG_TARGET})
|
||||
set_target_properties( ${CTG_TARGET} PROPERTIES FOLDER "Clang tablegenning")
|
||||
set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET})
|
||||
endif()
|
||||
endfunction(clang_tablegen)
|
||||
|
||||
macro(set_clang_windows_version_resource_properties name)
|
||||
if(DEFINED windows_resource_file)
|
||||
set_windows_version_resource_properties(${name} ${windows_resource_file}
|
||||
VERSION_MAJOR ${CLANG_VERSION_MAJOR}
|
||||
VERSION_MINOR ${CLANG_VERSION_MINOR}
|
||||
VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL}
|
||||
VERSION_STRING "${CLANG_VERSION} (${BACKEND_PACKAGE_STRING})"
|
||||
PRODUCT_NAME "clang")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(add_clang_subdirectory name)
|
||||
add_llvm_subdirectory(CLANG TOOL ${name})
|
||||
endmacro()
|
||||
|
||||
macro(add_clang_library name)
|
||||
cmake_parse_arguments(ARG
|
||||
"SHARED"
|
||||
""
|
||||
"ADDITIONAL_HEADERS"
|
||||
${ARGN})
|
||||
set(srcs)
|
||||
if(MSVC_IDE OR XCODE)
|
||||
# Add public headers
|
||||
file(RELATIVE_PATH lib_path
|
||||
${CLANG_SOURCE_DIR}/lib/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
if(NOT lib_path MATCHES "^[.][.]")
|
||||
file( GLOB_RECURSE headers
|
||||
${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.h
|
||||
${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.def
|
||||
)
|
||||
set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
|
||||
file( GLOB_RECURSE tds
|
||||
${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.td
|
||||
)
|
||||
source_group("TableGen descriptions" FILES ${tds})
|
||||
set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
|
||||
if(headers OR tds)
|
||||
set(srcs ${headers} ${tds})
|
||||
endif()
|
||||
endif()
|
||||
endif(MSVC_IDE OR XCODE)
|
||||
if(srcs OR ARG_ADDITIONAL_HEADERS)
|
||||
set(srcs
|
||||
ADDITIONAL_HEADERS
|
||||
${srcs}
|
||||
${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args.
|
||||
)
|
||||
endif()
|
||||
if(ARG_SHARED)
|
||||
set(ARG_ENABLE_SHARED SHARED)
|
||||
endif()
|
||||
llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS} ${srcs})
|
||||
|
||||
if(TARGET ${name})
|
||||
target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS})
|
||||
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
|
||||
install(TARGETS ${name}
|
||||
COMPONENT ${name}
|
||||
EXPORT ClangTargets
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
RUNTIME DESTINATION bin)
|
||||
|
||||
if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${name}
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${name}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name})
|
||||
else()
|
||||
# Add empty "phony" target
|
||||
add_custom_target(${name})
|
||||
endif()
|
||||
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Clang libraries")
|
||||
set_clang_windows_version_resource_properties(${name})
|
||||
endmacro(add_clang_library)
|
||||
|
||||
macro(add_clang_executable name)
|
||||
add_llvm_executable( ${name} ${ARGN} )
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Clang executables")
|
||||
set_clang_windows_version_resource_properties(${name})
|
||||
endmacro(add_clang_executable)
|
||||
|
||||
macro(add_clang_tool name)
|
||||
if (NOT CLANG_BUILD_TOOLS)
|
||||
set(EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
|
||||
add_clang_executable(${name} ${ARGN})
|
||||
|
||||
if (CLANG_BUILD_TOOLS)
|
||||
install(TARGETS ${name}
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT ${name})
|
||||
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${name}
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${name}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(add_clang_symlink name dest)
|
||||
add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE)
|
||||
# Always generate install targets
|
||||
llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE)
|
||||
endmacro()
|
||||
47
cmake/modules/CMakeLists.txt
Normal file
47
cmake/modules/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Generate a list of CMake library targets so that other CMake projects can
|
||||
# link against them. LLVM calls its version of this file LLVMExports.cmake, but
|
||||
# the usual CMake convention seems to be ${Project}Targets.cmake.
|
||||
set(CLANG_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/clang)
|
||||
set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}")
|
||||
|
||||
get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS)
|
||||
export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake)
|
||||
|
||||
# Generate ClangConfig.cmake for the build tree.
|
||||
set(CLANG_CONFIG_CMAKE_DIR "${clang_cmake_builddir}")
|
||||
set(CLANG_CONFIG_EXPORTS_FILE "${clang_cmake_builddir}/ClangTargets.cmake")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in
|
||||
${clang_cmake_builddir}/ClangConfig.cmake
|
||||
@ONLY)
|
||||
set(CLANG_CONFIG_CMAKE_DIR)
|
||||
set(CLANG_CONFIG_EXPORTS_FILE)
|
||||
|
||||
# Generate ClangConfig.cmake for the install tree.
|
||||
set(CLANG_CONFIG_CODE "
|
||||
# Compute the installation prefix from this LLVMConfig.cmake file location.
|
||||
get_filename_component(CLANG_INSTALL_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)")
|
||||
# Construct the proper number of get_filename_component(... PATH)
|
||||
# calls to compute the installation prefix.
|
||||
string(REGEX REPLACE "/" ";" _count "${CLANG_INSTALL_PACKAGE_DIR}")
|
||||
foreach(p ${_count})
|
||||
set(CLANG_CONFIG_CODE "${CLANG_CONFIG_CODE}
|
||||
get_filename_component(CLANG_INSTALL_PREFIX \"\${CLANG_INSTALL_PREFIX}\" PATH)")
|
||||
endforeach(p)
|
||||
set(CLANG_CONFIG_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${CLANG_INSTALL_PACKAGE_DIR}")
|
||||
set(CLANG_CONFIG_EXPORTS_FILE "\${CLANG_CMAKE_DIR}/ClangTargets.cmake")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake
|
||||
@ONLY)
|
||||
set(CLANG_CONFIG_CODE)
|
||||
set(CLANG_CONFIG_CMAKE_DIR)
|
||||
set(CLANG_CONFIG_EXPORTS_FILE)
|
||||
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake
|
||||
DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
|
||||
endif()
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# This file allows users to call find_package(Clang) and pick up our targets.
|
||||
|
||||
# Clang doesn't have any CMake configuration settings yet because it mostly
|
||||
# uses LLVM's. When it does, we should move this file to ClangConfig.cmake.in
|
||||
# and call configure_file() on it.
|
||||
|
||||
# Provide all our library targets to users.
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/ClangTargets.cmake")
|
||||
11
cmake/modules/ClangConfig.cmake.in
Normal file
11
cmake/modules/ClangConfig.cmake.in
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# This file allows users to call find_package(Clang) and pick up our targets.
|
||||
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
|
||||
@CLANG_CONFIG_CODE@
|
||||
|
||||
set(CLANG_EXPORTED_TARGETS "@CLANG_EXPORTS@")
|
||||
set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@")
|
||||
|
||||
# Provide all our library targets to users.
|
||||
include("@CLANG_CONFIG_EXPORTS_FILE@")
|
||||
|
|
@ -232,6 +232,23 @@ problems happening in certain source files or with certain global variables.
|
|||
type:*BadInitClassSubstring*=init
|
||||
src:bad/init/files/*=init
|
||||
|
||||
Suppressing memory leaks
|
||||
------------------------
|
||||
|
||||
Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part
|
||||
of AddressSanitizer) can be suppressed by a separate file passed as
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
LSAN_OPTIONS=suppressions=MyLSan.supp
|
||||
|
||||
which contains lines of the form `leak:<pattern>`. Memory leak will be
|
||||
suppressed if pattern matches any function name, source file name, or
|
||||
library name in the symbolized stack trace of the leak report. See
|
||||
`full documentation
|
||||
<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions>`_
|
||||
for more details.
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -95,6 +95,10 @@ if (LLVM_ENABLE_SPHINX)
|
|||
include(AddSphinxTarget)
|
||||
if (${SPHINX_OUTPUT_HTML})
|
||||
add_sphinx_target(html clang)
|
||||
add_custom_command(TARGET docs-clang-html POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/LibASTMatchersReference.html"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/html/LibASTMatchersReference.html")
|
||||
endif()
|
||||
if (${SPHINX_OUTPUT_MAN})
|
||||
add_sphinx_target(man clang)
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ In an SVN client, you can do:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
|
||||
svn diff --diff-cmd=diff -x -U0 | clang-format-diff.py -i
|
||||
|
||||
The :option:`-U0` will create a diff without context lines (the script would format
|
||||
The option `-U0` will create a diff without context lines (the script would format
|
||||
those as well).
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ the configuration (without a prefix: ``Auto``).
|
|||
If ``true``, horizontally aligns arguments after an open bracket.
|
||||
|
||||
This applies to round brackets (parentheses), angle brackets and square
|
||||
brackets. This will result in formattings like
|
||||
brackets.
|
||||
|
||||
Possible values:
|
||||
|
||||
|
|
@ -165,6 +165,7 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
someLongFunction(argument1,
|
||||
argument2);
|
||||
|
||||
* ``BAS_DontAlign`` (in configuration: ``DontAlign``)
|
||||
Don't align, instead use ``ContinuationIndentWidth``, e.g.:
|
||||
|
||||
|
|
@ -172,6 +173,7 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
someLongFunction(argument1,
|
||||
argument2);
|
||||
|
||||
* ``BAS_AlwaysBreak`` (in configuration: ``AlwaysBreak``)
|
||||
Always break after an open bracket, if the parameters don't fit
|
||||
on a single line, e.g.:
|
||||
|
|
@ -182,6 +184,7 @@ the configuration (without a prefix: ``Auto``).
|
|||
argument1, argument2);
|
||||
|
||||
|
||||
|
||||
**AlignConsecutiveAssignments** (``bool``)
|
||||
If ``true``, aligns consecutive assignments.
|
||||
|
||||
|
|
@ -214,6 +217,14 @@ the configuration (without a prefix: ``Auto``).
|
|||
If ``true``, horizontally align operands of binary and ternary
|
||||
expressions.
|
||||
|
||||
Specifically, this aligns operands of a single expression that needs to be
|
||||
split over multiple lines, e.g.:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
int aaa = bbbbbbbbbbbbbbb +
|
||||
ccccccccccccccc;
|
||||
|
||||
**AlignTrailingComments** (``bool``)
|
||||
If ``true``, aligns trailing comments.
|
||||
|
||||
|
|
@ -230,28 +241,31 @@ the configuration (without a prefix: ``Auto``).
|
|||
If ``true``, short case labels will be contracted to a single line.
|
||||
|
||||
**AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``)
|
||||
Dependent on the value, ``int f() { return 0; }`` can be put
|
||||
on a single line.
|
||||
Dependent on the value, ``int f() { return 0; }`` can be put on a
|
||||
single line.
|
||||
|
||||
Possible values:
|
||||
|
||||
* ``SFS_None`` (in configuration: ``None``)
|
||||
Never merge functions into a single line.
|
||||
|
||||
* ``SFS_Empty`` (in configuration: ``Empty``)
|
||||
Only merge empty functions.
|
||||
|
||||
* ``SFS_Inline`` (in configuration: ``Inline``)
|
||||
Only merge functions defined inside a class. Implies "empty".
|
||||
|
||||
* ``SFS_All`` (in configuration: ``All``)
|
||||
Merge all functions fitting on a single line.
|
||||
|
||||
|
||||
|
||||
**AllowShortIfStatementsOnASingleLine** (``bool``)
|
||||
If ``true``, ``if (a) return;`` can be put on a single
|
||||
line.
|
||||
If ``true``, ``if (a) return;`` can be put on a single line.
|
||||
|
||||
**AllowShortLoopsOnASingleLine** (``bool``)
|
||||
If ``true``, ``while (true) continue;`` can be put on a
|
||||
single line.
|
||||
If ``true``, ``while (true) continue;`` can be put on a single
|
||||
line.
|
||||
|
||||
**AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``)
|
||||
The function definition return type breaking style to use. This
|
||||
|
|
@ -262,12 +276,15 @@ the configuration (without a prefix: ``Auto``).
|
|||
* ``DRTBS_None`` (in configuration: ``None``)
|
||||
Break after return type automatically.
|
||||
``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
|
||||
|
||||
* ``DRTBS_All`` (in configuration: ``All``)
|
||||
Always break after the return type.
|
||||
|
||||
* ``DRTBS_TopLevel`` (in configuration: ``TopLevel``)
|
||||
Always break after the return types of top-level functions.
|
||||
|
||||
|
||||
|
||||
**AlwaysBreakAfterReturnType** (``ReturnTypeBreakingStyle``)
|
||||
The function declaration return type breaking style to use.
|
||||
|
||||
|
|
@ -276,16 +293,21 @@ the configuration (without a prefix: ``Auto``).
|
|||
* ``RTBS_None`` (in configuration: ``None``)
|
||||
Break after return type automatically.
|
||||
``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
|
||||
|
||||
* ``RTBS_All`` (in configuration: ``All``)
|
||||
Always break after the return type.
|
||||
|
||||
* ``RTBS_TopLevel`` (in configuration: ``TopLevel``)
|
||||
Always break after the return types of top-level functions.
|
||||
|
||||
* ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``)
|
||||
Always break after the return type of function definitions.
|
||||
|
||||
* ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``)
|
||||
Always break after the return type of top-level definitions.
|
||||
|
||||
|
||||
|
||||
**AlwaysBreakBeforeMultilineStrings** (``bool``)
|
||||
If ``true``, always break before multiline string literals.
|
||||
|
||||
|
|
@ -295,8 +317,8 @@ the configuration (without a prefix: ``Auto``).
|
|||
``ContinuationIndentWidth`` spaces from the start of the line.
|
||||
|
||||
**AlwaysBreakTemplateDeclarations** (``bool``)
|
||||
If ``true``, always break after the ``template<...>`` of a
|
||||
template declaration.
|
||||
If ``true``, always break after the ``template<...>`` of a template
|
||||
declaration.
|
||||
|
||||
**BinPackArguments** (``bool``)
|
||||
If ``false``, a function call's arguments will either be all on the
|
||||
|
|
@ -309,17 +331,17 @@ the configuration (without a prefix: ``Auto``).
|
|||
**BraceWrapping** (``BraceWrappingFlags``)
|
||||
Control of individual brace wrapping cases.
|
||||
|
||||
If ``BreakBeforeBraces`` is set to ``custom``, use this to specify how each
|
||||
individual brace case should be handled. Otherwise, this is ignored.
|
||||
If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how
|
||||
each individual brace case should be handled. Otherwise, this is ignored.
|
||||
|
||||
Nested configuration flags:
|
||||
|
||||
* ``bool AfterClass`` Wrap class definitions.
|
||||
* ``bool AfterControlStatement`` Wrap control statements (if/for/while/switch/..).
|
||||
* ``bool AfterControlStatement`` Wrap control statements (``if``/``for``/``while``/``switch``/..).
|
||||
* ``bool AfterEnum`` Wrap enum definitions.
|
||||
* ``bool AfterFunction`` Wrap function definitions.
|
||||
* ``bool AfterNamespace`` Wrap namespace definitions.
|
||||
* ``bool AfterObjCDeclaration`` Wrap ObjC definitions (@autoreleasepool, interfaces, ..).
|
||||
* ``bool AfterObjCDeclaration`` Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..).
|
||||
* ``bool AfterStruct`` Wrap struct definitions.
|
||||
* ``bool AfterUnion`` Wrap union definitions.
|
||||
* ``bool BeforeCatch`` Wrap before ``catch``.
|
||||
|
|
@ -337,12 +359,15 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``BOS_None`` (in configuration: ``None``)
|
||||
Break after operators.
|
||||
|
||||
* ``BOS_NonAssignment`` (in configuration: ``NonAssignment``)
|
||||
Break before operators that aren't assignments.
|
||||
|
||||
* ``BOS_All`` (in configuration: ``All``)
|
||||
Break before operators.
|
||||
|
||||
|
||||
|
||||
**BreakBeforeBraces** (``BraceBreakingStyle``)
|
||||
The brace breaking style to use.
|
||||
|
||||
|
|
@ -350,24 +375,33 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``BS_Attach`` (in configuration: ``Attach``)
|
||||
Always attach braces to surrounding context.
|
||||
|
||||
* ``BS_Linux`` (in configuration: ``Linux``)
|
||||
Like ``Attach``, but break before braces on function, namespace and
|
||||
class definitions.
|
||||
|
||||
* ``BS_Mozilla`` (in configuration: ``Mozilla``)
|
||||
Like ``Attach``, but break before braces on enum, function, and record
|
||||
definitions.
|
||||
|
||||
* ``BS_Stroustrup`` (in configuration: ``Stroustrup``)
|
||||
Like ``Attach``, but break before function definitions, 'catch', and 'else'.
|
||||
Like ``Attach``, but break before function definitions, ``catch``, and
|
||||
``else``.
|
||||
|
||||
* ``BS_Allman`` (in configuration: ``Allman``)
|
||||
Always break before braces.
|
||||
|
||||
* ``BS_GNU`` (in configuration: ``GNU``)
|
||||
Always break before braces and add an extra level of indentation to
|
||||
braces of control statements, not to those of class, function
|
||||
or other definitions.
|
||||
|
||||
* ``BS_WebKit`` (in configuration: ``WebKit``)
|
||||
Like ``Attach``, but break before functions.
|
||||
|
||||
* ``BS_Custom`` (in configuration: ``Custom``)
|
||||
Configure each individual brace in ``BraceWrapping``.
|
||||
Configure each individual brace in `BraceWrapping`.
|
||||
|
||||
|
||||
|
||||
**BreakBeforeTernaryOperators** (``bool``)
|
||||
|
|
@ -377,6 +411,9 @@ the configuration (without a prefix: ``Auto``).
|
|||
Always break constructor initializers before commas and align
|
||||
the commas with the colon.
|
||||
|
||||
**BreakStringLiterals** (``bool``)
|
||||
Allow breaking string literals when formatting.
|
||||
|
||||
**ColumnLimit** (``unsigned``)
|
||||
The column limit.
|
||||
|
||||
|
|
@ -416,7 +453,8 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
**DerivePointerAlignment** (``bool``)
|
||||
If ``true``, analyze the formatted file for the most common
|
||||
alignment of & and \*. ``PointerAlignment`` is then used only as fallback.
|
||||
alignment of ``&`` and ``\*``. ``PointerAlignment`` is then used only as
|
||||
fallback.
|
||||
|
||||
**DisableFormat** (``bool``)
|
||||
Disables formatting completely.
|
||||
|
|
@ -446,30 +484,32 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
In the .clang-format configuration file, this can be configured like:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: yaml
|
||||
|
||||
ForEachMacros: ['RANGES_FOR', 'FOREACH']
|
||||
|
||||
For example: BOOST_FOREACH.
|
||||
|
||||
**IncludeCategories** (``std::vector<IncludeCategory>``)
|
||||
Regular expressions denoting the different #include categories used
|
||||
for ordering #includes.
|
||||
Regular expressions denoting the different ``#include`` categories
|
||||
used for ordering ``#includes``.
|
||||
|
||||
These regular expressions are matched against the filename of an include
|
||||
(including the <> or "") in order. The value belonging to the first
|
||||
matching regular expression is assigned and #includes are sorted first
|
||||
matching regular expression is assigned and ``#includes`` are sorted first
|
||||
according to increasing category number and then alphabetically within
|
||||
each category.
|
||||
|
||||
If none of the regular expressions match, UINT_MAX is assigned as
|
||||
category. The main header for a source file automatically gets category 0,
|
||||
so that it is kept at the beginning of the #includes
|
||||
(http://llvm.org/docs/CodingStandards.html#include-style).
|
||||
If none of the regular expressions match, INT_MAX is assigned as
|
||||
category. The main header for a source file automatically gets category 0.
|
||||
so that it is generally kept at the beginning of the ``#includes``
|
||||
(http://llvm.org/docs/CodingStandards.html#include-style). However, you
|
||||
can also assign negative priorities if you have certain headers that
|
||||
always need to be first.
|
||||
|
||||
To configure this in the .clang-format file, use:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: yaml
|
||||
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
|
|
@ -479,6 +519,19 @@ the configuration (without a prefix: ``Auto``).
|
|||
- Regex: '.\*'
|
||||
Priority: 1
|
||||
|
||||
**IncludeIsMainRegex** (``std::string``)
|
||||
Specify a regular expression of suffixes that are allowed in the
|
||||
file-to-main-include mapping.
|
||||
|
||||
When guessing whether a #include is the "main" include (to assign
|
||||
category 0, see above), use this regex of allowed suffixes to the header
|
||||
stem. A partial match is done, so that:
|
||||
- "" means "arbitrary suffix"
|
||||
- "$" means "no suffix"
|
||||
|
||||
For example, if configured to "(_test)?$", then a header a.h would be seen
|
||||
as the "main" include in both a.cc and a_test.cc.
|
||||
|
||||
**IndentCaseLabels** (``bool``)
|
||||
Indent case labels one level from the switch statement.
|
||||
|
||||
|
|
@ -492,6 +545,22 @@ the configuration (without a prefix: ``Auto``).
|
|||
Indent if a function definition or declaration is wrapped after the
|
||||
type.
|
||||
|
||||
**JavaScriptQuotes** (``JavaScriptQuoteStyle``)
|
||||
The JavaScriptQuoteStyle to use for JavaScript strings.
|
||||
|
||||
Possible values:
|
||||
|
||||
* ``JSQS_Leave`` (in configuration: ``Leave``)
|
||||
Leave string quotes as they are.
|
||||
|
||||
* ``JSQS_Single`` (in configuration: ``Single``)
|
||||
Always use single quotes.
|
||||
|
||||
* ``JSQS_Double`` (in configuration: ``Double``)
|
||||
Always use double quotes.
|
||||
|
||||
|
||||
|
||||
**KeepEmptyLinesAtTheStartOfBlocks** (``bool``)
|
||||
If true, empty lines at the start of blocks are kept.
|
||||
|
||||
|
|
@ -502,16 +571,24 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``LK_None`` (in configuration: ``None``)
|
||||
Do not use.
|
||||
|
||||
* ``LK_Cpp`` (in configuration: ``Cpp``)
|
||||
Should be used for C, C++, ObjectiveC, ObjectiveC++.
|
||||
|
||||
* ``LK_Java`` (in configuration: ``Java``)
|
||||
Should be used for Java.
|
||||
|
||||
* ``LK_JavaScript`` (in configuration: ``JavaScript``)
|
||||
Should be used for JavaScript.
|
||||
|
||||
* ``LK_Proto`` (in configuration: ``Proto``)
|
||||
Should be used for Protocol Buffers
|
||||
(https://developers.google.com/protocol-buffers/).
|
||||
|
||||
* ``LK_TableGen`` (in configuration: ``TableGen``)
|
||||
Should be used for TableGen code.
|
||||
|
||||
|
||||
|
||||
**MacroBlockBegin** (``std::string``)
|
||||
A regular expression matching macros that start a block.
|
||||
|
|
@ -529,25 +606,28 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``NI_None`` (in configuration: ``None``)
|
||||
Don't indent in namespaces.
|
||||
|
||||
* ``NI_Inner`` (in configuration: ``Inner``)
|
||||
Indent only in inner namespaces (nested in other namespaces).
|
||||
|
||||
* ``NI_All`` (in configuration: ``All``)
|
||||
Indent in all namespaces.
|
||||
|
||||
|
||||
|
||||
**ObjCBlockIndentWidth** (``unsigned``)
|
||||
The number of characters to use for indentation of ObjC blocks.
|
||||
|
||||
**ObjCSpaceAfterProperty** (``bool``)
|
||||
Add a space after ``@property`` in Objective-C, i.e. use
|
||||
``\@property (readonly)`` instead of ``\@property(readonly)``.
|
||||
``@property (readonly)`` instead of ``@property(readonly)``.
|
||||
|
||||
**ObjCSpaceBeforeProtocolList** (``bool``)
|
||||
Add a space in front of an Objective-C protocol list, i.e. use
|
||||
``Foo <Protocol>`` instead of ``Foo<Protocol>``.
|
||||
|
||||
**PenaltyBreakBeforeFirstCallParameter** (``unsigned``)
|
||||
The penalty for breaking a function call after "call(".
|
||||
The penalty for breaking a function call after ``call(``.
|
||||
|
||||
**PenaltyBreakComment** (``unsigned``)
|
||||
The penalty for each line break introduced inside a comment.
|
||||
|
|
@ -572,12 +652,21 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``PAS_Left`` (in configuration: ``Left``)
|
||||
Align pointer to the left.
|
||||
|
||||
* ``PAS_Right`` (in configuration: ``Right``)
|
||||
Align pointer to the right.
|
||||
|
||||
* ``PAS_Middle`` (in configuration: ``Middle``)
|
||||
Align pointer in the middle.
|
||||
|
||||
|
||||
|
||||
**ReflowComments** (``bool``)
|
||||
If ``true``, clang-format will attempt to re-flow comments.
|
||||
|
||||
**SortIncludes** (``bool``)
|
||||
If ``true``, clang-format will sort ``#includes``.
|
||||
|
||||
**SpaceAfterCStyleCast** (``bool``)
|
||||
If ``true``, a space may be inserted after C style casts.
|
||||
|
||||
|
|
@ -591,9 +680,11 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``SBPO_Never`` (in configuration: ``Never``)
|
||||
Never put a space before opening parentheses.
|
||||
|
||||
* ``SBPO_ControlStatements`` (in configuration: ``ControlStatements``)
|
||||
Put a space before opening parentheses only after control statement
|
||||
keywords (``for/if/while...``).
|
||||
|
||||
* ``SBPO_Always`` (in configuration: ``Always``)
|
||||
Always put a space before opening parentheses, except when it's
|
||||
prohibited by the syntax rules (in function-like macro definitions) or
|
||||
|
|
@ -601,19 +692,21 @@ the configuration (without a prefix: ``Auto``).
|
|||
parentheses, etc.)
|
||||
|
||||
|
||||
|
||||
**SpaceInEmptyParentheses** (``bool``)
|
||||
If ``true``, spaces may be inserted into '()'.
|
||||
If ``true``, spaces may be inserted into ``()``.
|
||||
|
||||
**SpacesBeforeTrailingComments** (``unsigned``)
|
||||
The number of spaces before trailing line comments
|
||||
(``//`` - comments).
|
||||
|
||||
This does not affect trailing block comments (``/**/`` - comments) as those
|
||||
commonly have different usage patterns and a number of special cases.
|
||||
This does not affect trailing block comments (``/*`` - comments) as
|
||||
those commonly have different usage patterns and a number of special
|
||||
cases.
|
||||
|
||||
**SpacesInAngles** (``bool``)
|
||||
If ``true``, spaces will be inserted after '<' and before '>' in
|
||||
template argument lists
|
||||
If ``true``, spaces will be inserted after ``<`` and before ``>``
|
||||
in template argument lists.
|
||||
|
||||
**SpacesInCStyleCastParentheses** (``bool``)
|
||||
If ``true``, spaces may be inserted into C style casts.
|
||||
|
|
@ -623,26 +716,28 @@ the configuration (without a prefix: ``Auto``).
|
|||
ObjC and Javascript array and dict literals).
|
||||
|
||||
**SpacesInParentheses** (``bool``)
|
||||
If ``true``, spaces will be inserted after '(' and before ')'.
|
||||
If ``true``, spaces will be inserted after ``(`` and before ``)``.
|
||||
|
||||
**SpacesInSquareBrackets** (``bool``)
|
||||
If ``true``, spaces will be inserted after '[' and before ']'.
|
||||
If ``true``, spaces will be inserted after ``[`` and before ``]``.
|
||||
|
||||
**Standard** (``LanguageStandard``)
|
||||
Format compatible with this standard, e.g. use
|
||||
``A<A<int> >`` instead of ``A<A<int>>`` for LS_Cpp03.
|
||||
Format compatible with this standard, e.g. use ``A<A<int> >``
|
||||
instead of ``A<A<int>>`` for ``LS_Cpp03``.
|
||||
|
||||
Possible values:
|
||||
|
||||
* ``LS_Cpp03`` (in configuration: ``Cpp03``)
|
||||
Use C++03-compatible syntax.
|
||||
|
||||
* ``LS_Cpp11`` (in configuration: ``Cpp11``)
|
||||
Use features of C++11 (e.g. ``A<A<int>>`` instead of
|
||||
``A<A<int> >``).
|
||||
Use features of C++11 (e.g. ``A<A<int>>`` instead of ``A<A<int> >``).
|
||||
|
||||
* ``LS_Auto`` (in configuration: ``Auto``)
|
||||
Automatic detection based on the input.
|
||||
|
||||
|
||||
|
||||
**TabWidth** (``unsigned``)
|
||||
The number of columns used for tab stops.
|
||||
|
||||
|
|
@ -653,20 +748,23 @@ the configuration (without a prefix: ``Auto``).
|
|||
|
||||
* ``UT_Never`` (in configuration: ``Never``)
|
||||
Never use tab.
|
||||
|
||||
* ``UT_ForIndentation`` (in configuration: ``ForIndentation``)
|
||||
Use tabs only for indentation.
|
||||
|
||||
* ``UT_Always`` (in configuration: ``Always``)
|
||||
Use tabs whenever we need to fill whitespace that spans at least from
|
||||
one tab stop to the next one.
|
||||
|
||||
|
||||
|
||||
.. END_FORMAT_STYLE_OPTIONS
|
||||
|
||||
Adding additional style options
|
||||
===============================
|
||||
|
||||
Each additional style option adds costs to the clang-format project. Some of
|
||||
these costs affect the clang-format developement itself, as we need to make
|
||||
these costs affect the clang-format development itself, as we need to make
|
||||
sure that any given combination of options work and that new features don't
|
||||
break any of the existing options in any way. There are also costs for end users
|
||||
as options become less discoverable and people have to think about and make a
|
||||
|
|
|
|||
|
|
@ -43,6 +43,26 @@ register a plugin in a library, use ``FrontendPluginRegistry::Add<>``:
|
|||
|
||||
static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description");
|
||||
|
||||
Defining pragmas
|
||||
================
|
||||
|
||||
Plugins can also define pragmas by declaring a ``PragmaHandler`` and
|
||||
registering it using ``PragmaHandlerRegistry::Add<>``:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Define a pragma handler for #pragma example_pragma
|
||||
class ExamplePragmaHandler : public PragmaHandler {
|
||||
public:
|
||||
ExamplePragmaHandler() : PragmaHandler("example_pragma") { }
|
||||
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &PragmaTok) {
|
||||
// Handle the pragma
|
||||
}
|
||||
};
|
||||
|
||||
static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description");
|
||||
|
||||
Putting it all together
|
||||
=======================
|
||||
|
||||
|
|
@ -54,21 +74,25 @@ the `latest version of PrintFunctionNames.cpp
|
|||
Running the plugin
|
||||
==================
|
||||
|
||||
|
||||
Using the cc1 command line
|
||||
--------------------------
|
||||
|
||||
To run a plugin, the dynamic library containing the plugin registry must be
|
||||
loaded via the :option:`-load` command line option. This will load all plugins
|
||||
loaded via the `-load` command line option. This will load all plugins
|
||||
that are registered, and you can select the plugins to run by specifying the
|
||||
:option:`-plugin` option. Additional parameters for the plugins can be passed with
|
||||
:option:`-plugin-arg-<plugin-name>`.
|
||||
`-plugin` option. Additional parameters for the plugins can be passed with
|
||||
`-plugin-arg-<plugin-name>`.
|
||||
|
||||
Note that those options must reach clang's cc1 process. There are two
|
||||
ways to do so:
|
||||
|
||||
* Directly call the parsing process by using the :option:`-cc1` option; this
|
||||
* Directly call the parsing process by using the `-cc1` option; this
|
||||
has the downside of not configuring the default header search paths, so
|
||||
you'll need to specify the full system path configuration on the command
|
||||
line.
|
||||
* Use clang as usual, but prefix all arguments to the cc1 process with
|
||||
:option:`-Xclang`.
|
||||
`-Xclang`.
|
||||
|
||||
For example, to run the ``print-function-names`` plugin over a source file in
|
||||
clang, first build the plugin, and then call clang with the plugin from the
|
||||
|
|
@ -88,3 +112,19 @@ source tree:
|
|||
Also see the print-function-name plugin example's
|
||||
`README <http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/README.txt?view=markup>`_
|
||||
|
||||
|
||||
Using the clang command line
|
||||
----------------------------
|
||||
|
||||
Using `-fplugin=plugin` on the clang command line passes the plugin
|
||||
through as an argument to `-load` on the cc1 command line. If the plugin
|
||||
class implements the ``getActionType`` method then the plugin is run
|
||||
automatically. For example, to run the plugin automatically after the main AST
|
||||
action (i.e. the same as using `-add-plugin`):
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Automatically run the plugin after the main AST action
|
||||
PluginASTAction::ActionType getActionType() override {
|
||||
return AddAfterMainAction;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ Language Selection and Mode Options
|
|||
(either via :option:`-fobjc-nonfragile-abi`, or because it is the platform
|
||||
default).
|
||||
|
||||
.. option:: -fobjc-nonfragile-abi
|
||||
.. option:: -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi
|
||||
|
||||
Enable use of the Objective-C non-fragile ABI. On platforms for which this is
|
||||
the default ABI, it can be disabled with :option:`-fno-objc-nonfragile-abi`.
|
||||
|
|
@ -253,22 +253,32 @@ Code Generation Options
|
|||
|
||||
Currently equivalent to :option:`-O3`
|
||||
|
||||
.. option:: -g
|
||||
.. option:: -g, -gline-tables-only, -gmodules
|
||||
|
||||
Generate debug information. Note that Clang debug information works best at -O0.
|
||||
Control debug information output. Note that Clang debug information works
|
||||
best at :option:`-O0`. When more than one option starting with `-g` is
|
||||
specified, the last one wins:
|
||||
|
||||
.. option:: -gmodules
|
||||
:option:`-g` Generate debug information.
|
||||
|
||||
Generate debug information that contains external references to
|
||||
types defined in clang modules or precompiled headers instead of
|
||||
emitting redundant debug type information into every object file.
|
||||
This option implies :option:`-fmodule-format=obj`.
|
||||
:option:`-gline-tables-only` Generate only line table debug information. This
|
||||
allows for symbolicated backtraces with inlining information, but does not
|
||||
include any information about variables, their locations or types.
|
||||
|
||||
:option:`-gmodules` Generate debug information that contains external
|
||||
references to types defined in Clang modules or precompiled headers instead
|
||||
of emitting redundant debug type information into every object file. This
|
||||
option transparently switches the Clang module format to object file
|
||||
containers that hold the Clang module together with the debug information.
|
||||
When compiling a program that uses Clang modules or precompiled headers,
|
||||
this option produces complete debug information with faster compile
|
||||
times and much smaller object files.
|
||||
|
||||
This option should not be used when building static libraries for
|
||||
distribution to other machines because the debug info will contain
|
||||
references to the module cache on the machine the object files in the
|
||||
library were built on.
|
||||
|
||||
This option should not be used when building static libraries for
|
||||
distribution to other machines because the debug info will contain
|
||||
references to the module cache on the machine the object files in
|
||||
the library were built on.
|
||||
|
||||
.. option:: -fstandalone-debug -fno-standalone-debug
|
||||
|
||||
Clang supports a number of optimizations to reduce the size of debug
|
||||
|
|
@ -300,7 +310,7 @@ Code Generation Options
|
|||
|
||||
This flag sets the default visibility level.
|
||||
|
||||
.. option:: -fcommon
|
||||
.. option:: -fcommon, -fno-common
|
||||
|
||||
This flag specifies that variables without initializers get common linkage.
|
||||
It can be disabled with :option:`-fno-common`.
|
||||
|
|
|
|||
|
|
@ -25,13 +25,25 @@ As currently implemented, all schemes rely on link-time optimization (LTO);
|
|||
so it is required to specify ``-flto``, and the linker used must support LTO,
|
||||
for example via the `gold plugin`_.
|
||||
|
||||
To allow the checks to be implemented efficiently, the program must be
|
||||
structured such that certain object files are compiled with CFI
|
||||
To allow the checks to be implemented efficiently, the program must
|
||||
be structured such that certain object files are compiled with CFI
|
||||
enabled, and are statically linked into the program. This may preclude
|
||||
the use of shared libraries in some cases. Experimental support for
|
||||
:ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that
|
||||
does not have these requirements. This cross-DSO support has unstable
|
||||
ABI at this time.
|
||||
the use of shared libraries in some cases.
|
||||
|
||||
The compiler will only produce CFI checks for a class if it can infer hidden
|
||||
LTO visibility for that class. LTO visibility is a property of a class that
|
||||
is inferred from flags and attributes. For more details, see the documentation
|
||||
for :doc:`LTO visibility <LTOVisibility>`.
|
||||
|
||||
The ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags
|
||||
require that a ``-fvisibility=`` flag also be specified. This is because the
|
||||
default visibility setting is ``-fvisibility=default``, which would disable
|
||||
CFI checks for classes without visibility attributes. Most users will want
|
||||
to specify ``-fvisibility=hidden``, which enables CFI checks for such classes.
|
||||
|
||||
Experimental support for :ref:`cross-DSO control flow integrity
|
||||
<cfi-cross-dso>` exists that does not require classes to have hidden LTO
|
||||
visibility. This cross-DSO support has unstable ABI at this time.
|
||||
|
||||
.. _gold plugin: http://llvm.org/docs/GoldPlugin.html
|
||||
|
||||
|
|
@ -129,7 +141,8 @@ type ``void*`` or another unrelated type (which can be checked with
|
|||
The difference between these two types of casts is that the first is defined
|
||||
by the C++ standard to produce an undefined value, while the second is not
|
||||
in itself undefined behavior (it is well defined to cast the pointer back
|
||||
to its original type).
|
||||
to its original type) unless the object is uninitialized and the cast is a
|
||||
``static_cast`` (see C++14 [basic.life]p5).
|
||||
|
||||
If a program as a matter of policy forbids the second type of cast, that
|
||||
restriction can normally be enforced. However it may in some cases be necessary
|
||||
|
|
@ -232,11 +245,6 @@ A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain
|
|||
source files, functions and types using the ``src``, ``fun`` and ``type``
|
||||
entity types.
|
||||
|
||||
In addition, if a type has a ``uuid`` attribute and the blacklist contains
|
||||
the type entry ``attr:uuid``, CFI checks are suppressed for that type. This
|
||||
allows all COM types to be easily blacklisted, which is useful as COM types
|
||||
are typically defined outside of the linked program.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Suppress checking for code in a file.
|
||||
|
|
@ -246,8 +254,6 @@ are typically defined outside of the linked program.
|
|||
fun:*MyFooBar*
|
||||
# Ignore all types in the standard library.
|
||||
type:std::*
|
||||
# Ignore all types with a uuid attribute.
|
||||
type:attr:uuid
|
||||
|
||||
.. _cfi-cross-dso:
|
||||
|
||||
|
|
@ -259,6 +265,11 @@ flow integrity mode, which allows all CFI schemes listed above to
|
|||
apply across DSO boundaries. As in the regular CFI, each DSO must be
|
||||
built with ``-flto``.
|
||||
|
||||
Normally, CFI checks will only be performed for classes that have hidden LTO
|
||||
visibility. With this flag enabled, the compiler will emit cross-DSO CFI
|
||||
checks for all classes, except for those which appear in the CFI blacklist
|
||||
or which use a ``no_sanitize`` attribute.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
|
|
|
|||
|
|
@ -90,10 +90,10 @@ For example on x86 a typical virtual call may look like this:
|
|||
|
||||
The compiler relies on co-operation from the linker in order to assemble
|
||||
the bit vectors for the whole program. It currently does this using LLVM's
|
||||
`bit sets`_ mechanism together with link-time optimization.
|
||||
`type metadata`_ mechanism together with link-time optimization.
|
||||
|
||||
.. _address point: https://mentorembedded.github.io/cxx-abi/abi.html#vtable-general
|
||||
.. _bit sets: http://llvm.org/docs/BitSets.html
|
||||
.. _type metadata: http://llvm.org/docs/TypeMetadata.html
|
||||
.. _ByteArrayBuilder: http://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html
|
||||
|
||||
Optimizations
|
||||
|
|
@ -196,7 +196,7 @@ those sub-hierarchies need to be (see "Stripping Leading/Trailing Zeros in Bit
|
|||
Vectors" above). The `GlobalLayoutBuilder`_ class is responsible for laying
|
||||
out the globals efficiently to minimize the sizes of the underlying bitsets.
|
||||
|
||||
.. _GlobalLayoutBuilder: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/LowerBitSets.h?view=markup
|
||||
.. _GlobalLayoutBuilder: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/LowerTypeTests.h?view=markup
|
||||
|
||||
Alignment
|
||||
~~~~~~~~~
|
||||
|
|
@ -297,8 +297,8 @@ file's symbol table, the symbols for the target functions also refer to the
|
|||
jump table entries, so that addresses taken outside the module will pass
|
||||
any verification done inside the module.
|
||||
|
||||
In more concrete terms, suppose we have three functions ``f``, ``g``, ``h``
|
||||
which are members of a single bitset, and a function foo that returns their
|
||||
In more concrete terms, suppose we have three functions ``f``, ``g``,
|
||||
``h`` which are all of the same type, and a function foo that returns their
|
||||
addresses:
|
||||
|
||||
.. code-block:: none
|
||||
|
|
@ -439,10 +439,10 @@ export this information, every DSO implements
|
|||
|
||||
void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr)
|
||||
|
||||
This function provides external modules with access to CFI checks for
|
||||
the targets inside this DSO. For each known ``CallSiteTypeId``, this
|
||||
functions performs an ``llvm.bitset.test`` with the corresponding bit
|
||||
set. It aborts if the type is unknown, or if the check fails.
|
||||
This function provides external modules with access to CFI checks for the
|
||||
targets inside this DSO. For each known ``CallSiteTypeId``, this function
|
||||
performs an ``llvm.type.test`` with the corresponding type identifier. It
|
||||
aborts if the type is unknown, or if the check fails.
|
||||
|
||||
The basic implementation is a large switch statement over all values
|
||||
of CallSiteTypeId supported by this DSO, and each case is similar to
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ when compiling your code.
|
|||
|
||||
On the other hand, Clang/LLVM is natively a cross-compiler, meaning that
|
||||
one set of programs can compile to all targets by setting the ``-target``
|
||||
option. That makes it a lot easier for programers wishing to compile to
|
||||
option. That makes it a lot easier for programmers wishing to compile to
|
||||
different platforms and architectures, and for compiler developers that
|
||||
only have to maintain one build system, and for OS distributions, that
|
||||
need only one set of main packages.
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ driver, but diagnostics can be :ref:`rendered in many different ways
|
|||
<DiagnosticClient>` depending on how the ``DiagnosticClient`` interface is
|
||||
implemented. A representative example of a diagnostic is:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: text
|
||||
|
||||
t.c:38:15: error: invalid operands to binary expression ('int *' and '_Complex float')
|
||||
P = (P-42) + Gamma*4;
|
||||
|
|
@ -374,7 +374,7 @@ use of a deprecated construct into something more palatable. Here is one such
|
|||
example from the C++ front end, where we warn about the right-shift operator
|
||||
changing meaning from C++98 to C++11:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: text
|
||||
|
||||
test.cpp:3:7: warning: use of right-shift operator ('>>') in template argument
|
||||
will require parentheses in C++11
|
||||
|
|
@ -514,7 +514,7 @@ Clang represents most source ranges by [first, last], where "first" and "last"
|
|||
each point to the beginning of their respective tokens. For example consider
|
||||
the ``SourceRange`` of the following statement:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: text
|
||||
|
||||
x = foo + bar;
|
||||
^first ^last
|
||||
|
|
@ -837,7 +837,7 @@ typedefs. For example, consider this code:
|
|||
The code above is illegal, and thus we expect there to be diagnostics emitted
|
||||
on the annotated lines. In this example, we expect to get:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: text
|
||||
|
||||
test.c:6:1: error: indirection requires pointer operand ('foo' invalid)
|
||||
*X; // error
|
||||
|
|
@ -1422,7 +1422,7 @@ pretty-printed version of the CFG to standard error. This is especially useful
|
|||
when one is using a debugger such as gdb. For example, here is the output of
|
||||
``FooCFG->dump()``:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: text
|
||||
|
||||
[ B5 (ENTRY) ]
|
||||
Predecessors (0):
|
||||
|
|
|
|||
107
docs/ItaniumMangleAbiTags.rst
Normal file
107
docs/ItaniumMangleAbiTags.rst
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
========
|
||||
ABI tags
|
||||
========
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This text tries to describe gcc semantic for mangling "abi_tag" attributes
|
||||
described in https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
|
||||
|
||||
There is no guarantee the following rules are correct, complete or make sense
|
||||
in any way as they were determined empirically by experiments with gcc5.
|
||||
|
||||
Declaration
|
||||
===========
|
||||
|
||||
ABI tags are declared in an abi_tag attribute and can be applied to a
|
||||
function, variable, class or inline namespace declaration. The attribute takes
|
||||
one or more strings (called tags); the order does not matter.
|
||||
|
||||
See https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html for
|
||||
details.
|
||||
|
||||
Tags on an inline namespace are called "implicit tags", all other tags are
|
||||
"explicit tags".
|
||||
|
||||
Mangling
|
||||
========
|
||||
|
||||
All tags that are "active" on an <unqualified-name> are emitted after the
|
||||
<unqualified-name>, before <template-args> or <discriminator>, and are part of
|
||||
the same <substitution> the <unqualified-name> is.
|
||||
|
||||
They are mangled as:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
<abi-tags> ::= <abi-tag>* # sort by name
|
||||
<abi-tag> ::= B <tag source-name>
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
__attribute__((abi_tag("test")))
|
||||
void Func();
|
||||
// gets mangled as: _Z4FuncB4testv (prettified as `Func[abi:test]()`)
|
||||
|
||||
Active tags
|
||||
===========
|
||||
|
||||
A namespace does not have any active tags. For types (class / struct / union /
|
||||
enum), the explicit tags are the active tags.
|
||||
|
||||
For variables and functions, the active tags are the explicit tags plus any
|
||||
"required tags" which are not in the "available tags" set:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
derived-tags := (required-tags - available-tags)
|
||||
active-tags := explicit-tags + derived-tags
|
||||
|
||||
Required tags for a function
|
||||
============================
|
||||
|
||||
If a function is used as a local scope for another name, and is part of
|
||||
another function as local scope, it doesn't have any required tags.
|
||||
|
||||
If a function is used as a local scope for a guard variable name, it doesn't
|
||||
have any required tags.
|
||||
|
||||
Otherwise the function requires any implicit or explicit tag used in the name
|
||||
for the return type.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
namespace A {
|
||||
inline namespace B __attribute__((abi_tag)) {
|
||||
struct C { int x; };
|
||||
}
|
||||
}
|
||||
|
||||
A::C foo(); // gets mangled as: _Z3fooB1Bv (prettified as `foo[abi:B]()`)
|
||||
|
||||
Required tags for a variable
|
||||
============================
|
||||
|
||||
A variable requires any implicit or explicit tag used in its type.
|
||||
|
||||
Available tags
|
||||
==============
|
||||
|
||||
All tags used in the prefix and in the template arguments for a name are
|
||||
available. Also, for functions, all tags from the <bare-function-type>
|
||||
(which might include the return type for template functions) are available.
|
||||
|
||||
For <local-name>s all active tags used in the local part (<function-
|
||||
encoding>) are available, but not implicit tags which were not active.
|
||||
|
||||
Implicit and explicit tags used in the <unqualified-name> for a function (as
|
||||
in the type of a cast operator) are NOT available.
|
||||
|
||||
Example: a cast operator to std::string (which is
|
||||
std::__cxx11::basic_string<...>) will use 'cxx11' as an active tag, as it is
|
||||
required from the return type `std::string` but not available.
|
||||
113
docs/LTOVisibility.rst
Normal file
113
docs/LTOVisibility.rst
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
==============
|
||||
LTO Visibility
|
||||
==============
|
||||
|
||||
*LTO visibility* is a property of an entity that specifies whether it can be
|
||||
referenced from outside the current LTO unit. A *linkage unit* is a set of
|
||||
translation units linked together into an executable or DSO, and a linkage
|
||||
unit's *LTO unit* is the subset of the linkage unit that is linked together
|
||||
using link-time optimization; in the case where LTO is not being used, the
|
||||
linkage unit's LTO unit is empty. Each linkage unit has only a single LTO unit.
|
||||
|
||||
The LTO visibility of a class is used by the compiler to determine which
|
||||
classes the virtual function call optimization and control flow integrity
|
||||
features apply to. These features use whole-program information, so they
|
||||
require the entire class hierarchy to be visible in order to work correctly.
|
||||
|
||||
If any translation unit in the program uses either of the virtual function
|
||||
call optimization or control flow integrity features, it is effectively an
|
||||
ODR violation to define a class with hidden LTO visibility in multiple linkage
|
||||
units. A class with public LTO visibility may be defined in multiple linkage
|
||||
units, but the tradeoff is that the virtual function call optimization and
|
||||
control flow integrity features can only be applied to classes with hidden LTO
|
||||
visibility. A class's LTO visibility is treated as an ODR-relevant property
|
||||
of its definition, so it must be consistent between translation units.
|
||||
|
||||
In translation units built with LTO, LTO visibility is based on the
|
||||
class's symbol visibility as expressed at the source level (i.e. the
|
||||
``__attribute__((visibility("...")))`` attribute, or the ``-fvisibility=``
|
||||
flag) or, on the Windows platform, the dllimport and dllexport attributes. When
|
||||
targeting non-Windows platforms, classes with a visibility other than hidden
|
||||
visibility receive public LTO visibility. When targeting Windows, classes
|
||||
with dllimport or dllexport attributes receive public LTO visibility. All
|
||||
other classes receive hidden LTO visibility. Classes with internal linkage
|
||||
(e.g. classes declared in unnamed namespaces) also receive hidden LTO
|
||||
visibility.
|
||||
|
||||
A class defined in a translation unit built without LTO receives public
|
||||
LTO visibility regardless of its object file visibility, linkage or other
|
||||
attributes.
|
||||
|
||||
This mechanism will produce the correct result in most cases, but there are
|
||||
two cases where it may wrongly infer hidden LTO visibility.
|
||||
|
||||
1. As a corollary of the above rules, if a linkage unit is produced from a
|
||||
combination of LTO object files and non-LTO object files, any hidden
|
||||
visibility class defined in both a translation unit built with LTO and
|
||||
a translation unit built without LTO must be defined with public LTO
|
||||
visibility in order to avoid an ODR violation.
|
||||
|
||||
2. Some ABIs provide the ability to define an abstract base class without
|
||||
visibility attributes in multiple linkage units and have virtual calls
|
||||
to derived classes in other linkage units work correctly. One example of
|
||||
this is COM on Windows platforms. If the ABI allows this, any base class
|
||||
used in this way must be defined with public LTO visibility.
|
||||
|
||||
Classes that fall into either of these categories can be marked up with the
|
||||
``[[clang::lto_visibility_public]]`` attribute. To specifically handle the
|
||||
COM case, classes with the ``__declspec(uuid())`` attribute receive public
|
||||
LTO visibility. On Windows platforms, clang-cl's ``/MT`` and ``/MTd``
|
||||
flags statically link the program against a prebuilt standard library;
|
||||
these flags imply public LTO visibility for every class declared in the
|
||||
``std`` and ``stdext`` namespaces.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
The following example shows how LTO visibility works in practice in several
|
||||
cases involving two linkage units, ``main`` and ``dso.so``.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
+-----------------------------------------------------------+ +----------------------------------------------------+
|
||||
| main (clang++ -fvisibility=hidden): | | dso.so (clang++ -fvisibility=hidden): |
|
||||
| | | |
|
||||
| +-----------------------------------------------------+ | | struct __attribute__((visibility("default"))) C { |
|
||||
| | LTO unit (clang++ -fvisibility=hidden -flto): | | | virtual void f(); |
|
||||
| | | | | } |
|
||||
| | struct A { ... }; | | | void C::f() {} |
|
||||
| | struct [[clang::lto_visibility_public]] B { ... }; | | | struct D { |
|
||||
| | struct __attribute__((visibility("default"))) C { | | | virtual void g() = 0; |
|
||||
| | virtual void f(); | | | }; |
|
||||
| | }; | | | struct E : D { |
|
||||
| | struct [[clang::lto_visibility_public]] D { | | | virtual void g() { ... } |
|
||||
| | virtual void g() = 0; | | | }; |
|
||||
| | }; | | | __attribute__(visibility("default"))) D *mkE() { |
|
||||
| | | | | return new E; |
|
||||
| +-----------------------------------------------------+ | | } |
|
||||
| | | |
|
||||
| struct B { ... }; | +----------------------------------------------------+
|
||||
| |
|
||||
+-----------------------------------------------------------+
|
||||
|
||||
We will now describe the LTO visibility of each of the classes defined in
|
||||
these linkage units.
|
||||
|
||||
Class ``A`` is not defined outside of ``main``'s LTO unit, so it can have
|
||||
hidden LTO visibility. This is inferred from the object file visibility
|
||||
specified on the command line.
|
||||
|
||||
Class ``B`` is defined in ``main``, both inside and outside its LTO unit. The
|
||||
definition outside the LTO unit has public LTO visibility, so the definition
|
||||
inside the LTO unit must also have public LTO visibility in order to avoid
|
||||
an ODR violation.
|
||||
|
||||
Class ``C`` is defined in both ``main`` and ``dso.so`` and therefore must
|
||||
have public LTO visibility. This is correctly inferred from the ``visibility``
|
||||
attribute.
|
||||
|
||||
Class ``D`` is an abstract base class with a derived class ``E`` defined
|
||||
in ``dso.so``. This is an example of the COM scenario; the definition of
|
||||
``D`` in ``main``'s LTO unit must have public LTO visibility in order to be
|
||||
compatible with the definition of ``D`` in ``dso.so``, which is observable
|
||||
by calling the function ``mkE``.
|
||||
|
|
@ -449,7 +449,7 @@ An optional string message can be added to the ``deprecated`` and
|
|||
If the deprecated or unavailable declaration is used, the message will be
|
||||
incorporated into the appropriate diagnostic:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: none
|
||||
|
||||
harmless.c:4:3: warning: 'explode' is deprecated: extremely unsafe, use 'combust' instead!!!
|
||||
[-Wdeprecated-declarations]
|
||||
|
|
@ -1022,6 +1022,7 @@ The following type trait primitives are supported by Clang:
|
|||
* ``__is_nothrow_assignable`` (MSVC 2013, clang)
|
||||
* ``__is_constructible`` (MSVC 2013, clang)
|
||||
* ``__is_nothrow_constructible`` (MSVC 2013, clang)
|
||||
* ``__is_assignable`` (MSVC 2015, clang)
|
||||
|
||||
Blocks
|
||||
======
|
||||
|
|
@ -1505,6 +1506,35 @@ C-style cast applied to each element of the first argument.
|
|||
|
||||
Query for this feature with ``__has_builtin(__builtin_convertvector)``.
|
||||
|
||||
``__builtin_bitreverse``
|
||||
------------------------
|
||||
|
||||
* ``__builtin_bitreverse8``
|
||||
* ``__builtin_bitreverse16``
|
||||
* ``__builtin_bitreverse32``
|
||||
* ``__builtin_bitreverse64``
|
||||
|
||||
**Syntax**:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
__builtin_bitreverse32(x)
|
||||
|
||||
**Examples**:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
uint8_t rev_x = __builtin_bitreverse8(x);
|
||||
uint16_t rev_x = __builtin_bitreverse16(x);
|
||||
uint32_t rev_y = __builtin_bitreverse32(y);
|
||||
uint64_t rev_z = __builtin_bitreverse64(z);
|
||||
|
||||
**Description**:
|
||||
|
||||
The '``__builtin_bitreverse``' family of builtins is used to reverse
|
||||
the bitpattern of an integer value; for example ``0b10110110`` becomes
|
||||
``0b01101101``.
|
||||
|
||||
``__builtin_unreachable``
|
||||
-------------------------
|
||||
|
||||
|
|
@ -1728,6 +1758,24 @@ convert their operands before performing the operation.
|
|||
|
||||
Query for this feature with ``__has_builtin(__builtin_add_overflow)``, etc.
|
||||
|
||||
Floating point builtins
|
||||
---------------------------------------
|
||||
|
||||
``__builtin_canonicalize``
|
||||
--------------------------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
double __builtin_canonicalize(double);
|
||||
float __builtin_canonicalizef(float);
|
||||
long double__builtin_canonicalizel(long double);
|
||||
|
||||
Returns the platform specific canonical encoding of a floating point
|
||||
number. This canonicalization is useful for implementing certain
|
||||
numeric primitives such as frexp. See `LLVM canonicalize intrinsic
|
||||
<http://llvm.org/docs/LangRef.html#llvm-canonicalize-intrinsic>`_ for
|
||||
more information on the semantics.
|
||||
|
||||
.. _langext-__c11_atomic:
|
||||
|
||||
__c11_atomic builtins
|
||||
|
|
@ -1857,7 +1905,7 @@ in the `ARM C Language Extensions Release 2.0
|
|||
<http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf>`_.
|
||||
Note that these intrinsics are implemented as motion barriers that block
|
||||
reordering of memory accesses and side effect instructions. Other instructions
|
||||
like simple arithmatic may be reordered around the intrinsic. If you expect to
|
||||
like simple arithmetic may be reordered around the intrinsic. If you expect to
|
||||
have no reordering at all, use inline assembly instead.
|
||||
|
||||
X86/X86-64 Language Extensions
|
||||
|
|
@ -1865,12 +1913,13 @@ X86/X86-64 Language Extensions
|
|||
|
||||
The X86 backend has these language extensions:
|
||||
|
||||
Memory references off the GS segment
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Memory references to specified segments
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Annotating a pointer with address space #256 causes it to be code generated
|
||||
relative to the X86 GS segment register, and address space #257 causes it to be
|
||||
relative to the X86 FS segment. Note that this is a very very low-level
|
||||
relative to the X86 GS segment register, address space #257 causes it to be
|
||||
relative to the X86 FS segment, and address space #258 causes it to be
|
||||
relative to the X86 SS segment. Note that this is a very very low-level
|
||||
feature that should only be used if you know what you're doing (for example in
|
||||
an OS kernel).
|
||||
|
||||
|
|
@ -2001,9 +2050,9 @@ Extensions for loop hint optimizations
|
|||
|
||||
The ``#pragma clang loop`` directive is used to specify hints for optimizing the
|
||||
subsequent for, while, do-while, or c++11 range-based for loop. The directive
|
||||
provides options for vectorization, interleaving, and unrolling. Loop hints can
|
||||
be specified before any loop and will be ignored if the optimization is not safe
|
||||
to apply.
|
||||
provides options for vectorization, interleaving, unrolling and
|
||||
distribution. Loop hints can be specified before any loop and will be ignored if
|
||||
the optimization is not safe to apply.
|
||||
|
||||
Vectorization and Interleaving
|
||||
------------------------------
|
||||
|
|
@ -2098,6 +2147,38 @@ to the same code size limit as with ``unroll(enable)``.
|
|||
|
||||
Unrolling of a loop can be prevented by specifying ``unroll(disable)``.
|
||||
|
||||
Loop Distribution
|
||||
-----------------
|
||||
|
||||
Loop Distribution allows splitting a loop into multiple loops. This is
|
||||
beneficial for example when the entire loop cannot be vectorized but some of the
|
||||
resulting loops can.
|
||||
|
||||
If ``distribute(enable))`` is specified and the loop has memory dependencies
|
||||
that inhibit vectorization, the compiler will attempt to isolate the offending
|
||||
operations into a new loop. This optimization is not enabled by default, only
|
||||
loops marked with the pragma are considered.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#pragma clang loop distribute(enable)
|
||||
for (i = 0; i < N; ++i) {
|
||||
S1: A[i + 1] = A[i] + B[i];
|
||||
S2: C[i] = D[i] * E[i];
|
||||
}
|
||||
|
||||
This loop will be split into two loops between statements S1 and S2. The
|
||||
second loop containing S2 will be vectorized.
|
||||
|
||||
Loop Distribution is currently not enabled by default in the optimizer because
|
||||
it can hurt performance in some cases. For example, instruction-level
|
||||
parallelism could be reduced by sequentializing the execution of the
|
||||
statements S1 and S2 above.
|
||||
|
||||
If Loop Distribution is turned on globally with
|
||||
``-mllvm -enable-loop-distribution``, specifying ``distribute(disable)`` can
|
||||
be used the disable it on a per-loop basis.
|
||||
|
||||
Additional Information
|
||||
----------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -9,21 +9,39 @@ Introduction
|
|||
============
|
||||
|
||||
LeakSanitizer is a run-time memory leak detector. It can be combined with
|
||||
:doc:`AddressSanitizer` to get both memory error and leak detection.
|
||||
LeakSanitizer does not introduce any additional slowdown when used in this mode.
|
||||
The LeakSanitizer runtime can also be linked in separately to get leak detection
|
||||
only, at a minimal performance cost.
|
||||
:doc:`AddressSanitizer` to get both memory error and leak detection, or
|
||||
used in a stand-alone mode. LSan adds almost no performance overhead
|
||||
until the very end of the process, at which point there is an extra leak
|
||||
detection phase.
|
||||
|
||||
Current status
|
||||
==============
|
||||
Usage
|
||||
=====
|
||||
|
||||
LeakSanitizer is turned on by default, but it is only supported on x86\_64
|
||||
Linux.
|
||||
LeakSanitizer is only supported on x86\_64 Linux. In order to use it,
|
||||
simply build your program with :doc:`AddressSanitizer`:
|
||||
|
||||
The combined mode has been tested on fairly large software projects. The
|
||||
stand-alone mode has received much less testing.
|
||||
.. code-block:: console
|
||||
|
||||
There are plans to support LeakSanitizer in :doc:`MemorySanitizer` builds.
|
||||
$ cat memory-leak.c
|
||||
#include <stdlib.h>
|
||||
void *p;
|
||||
int main() {
|
||||
p = malloc(7);
|
||||
p = 0; // The memory is leaked here.
|
||||
return 0;
|
||||
}
|
||||
% clang -fsanitize=address -g memory-leak.c ; ./a.out
|
||||
==23646==ERROR: LeakSanitizer: detected memory leaks
|
||||
Direct leak of 7 byte(s) in 1 object(s) allocated from:
|
||||
#0 0x4af01b in __interceptor_malloc /projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3
|
||||
#1 0x4da26a in main memory-leak.c:4:7
|
||||
#2 0x7f076fd9cec4 in __libc_start_main libc-start.c:287
|
||||
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s).
|
||||
|
||||
To use LeakSanitizer in stand-alone mode, link your program with
|
||||
``-fsanitize=leak`` flag. Make sure to use ``clang`` (not ``ld``) for the
|
||||
link step, so that it would link in proper LeakSanitizer run-time library
|
||||
into the final executable.
|
||||
|
||||
More Information
|
||||
================
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -84,18 +84,23 @@ The status of major ABI-impacting C++ features:
|
|||
* RTTI: :good:`Complete`. Generation of RTTI data structures has been
|
||||
finished, along with support for the ``/GR`` flag.
|
||||
|
||||
* Exceptions and SEH: :partial:`Partial`.
|
||||
C++ exceptions (``try`` / ``catch`` / ``throw``) and
|
||||
structured exceptions (``__try`` / ``__except`` / ``__finally``) mostly
|
||||
work on x64. 32-bit exception handling support is being worked on. LLVM does
|
||||
not model asynchronous exceptions, so it is currently impossible to catch an
|
||||
asynchronous exception generated in the same frame as the catching ``__try``.
|
||||
* C++ Exceptions: :good:`Mostly complete`. Support for
|
||||
C++ exceptions (``try`` / ``catch`` / ``throw``) have been implemented for
|
||||
x86 and x64. Our implementation has been well tested but we still get the
|
||||
odd bug report now and again.
|
||||
C++ exception specifications are ignored, but this is `consistent with Visual
|
||||
C++`_.
|
||||
|
||||
.. _consistent with Visual C++:
|
||||
https://msdn.microsoft.com/en-us/library/wfa0edys.aspx
|
||||
|
||||
* Asynchronous Exceptions (SEH): :partial:`Partial`.
|
||||
Structured exceptions (``__try`` / ``__except`` / ``__finally``) mostly
|
||||
work on x86 and x64.
|
||||
LLVM does not model asynchronous exceptions, so it is currently impossible to
|
||||
catch an asynchronous exception generated in the same frame as the catching
|
||||
``__try``.
|
||||
|
||||
* Thread-safe initialization of local statics: :good:`Complete`. MSVC 2015
|
||||
added support for thread-safe initialization of such variables by taking an
|
||||
ABI break.
|
||||
|
|
|
|||
110
docs/Makefile
110
docs/Makefile
|
|
@ -1,110 +0,0 @@
|
|||
##===- docs/Makefile ---------------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL := ..
|
||||
|
||||
ifdef BUILD_FOR_WEBSITE
|
||||
PROJ_OBJ_DIR = .
|
||||
DOXYGEN = doxygen
|
||||
|
||||
$(PROJ_OBJ_DIR)/doxygen.cfg: doxygen.cfg.in
|
||||
cat $< | sed \
|
||||
-e 's/@DOT@/dot/g' \
|
||||
-e 's/@PACKAGE_VERSION@/mainline/' \
|
||||
-e 's/@abs_builddir@/./g' \
|
||||
-e 's/@abs_srcdir@/./g' \
|
||||
-e 's/@clang_doxygen_generate_qhp@/NO/g' \
|
||||
-e 's/@clang_doxygen_qch_filename@//g' \
|
||||
-e 's/@clang_doxygen_qhelpgenerator_path@//g' \
|
||||
-e 's/@clang_doxygen_qhp_cust_filter_attrs@//g' \
|
||||
-e 's/@clang_doxygen_qhp_cust_filter_name@//g' \
|
||||
-e 's/@clang_doxygen_qhp_namespace@//g' \
|
||||
-e 's/@enable_external_search@/NO/g' \
|
||||
-e 's/@enable_searchengine@/NO/g' \
|
||||
-e 's/@enable_server_based_search@/NO/g' \
|
||||
-e 's/@extra_search_mappings@//g' \
|
||||
-e 's/@searchengine_url@//g' \
|
||||
-e 's/@DOT_IMAGE_FORMAT@/png/g' \
|
||||
> $@
|
||||
endif
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
HTML := $(wildcard $(PROJ_SRC_DIR)/*.html) \
|
||||
$(wildcard $(PROJ_SRC_DIR)/*.css)
|
||||
#IMAGES := $(wildcard $(PROJ_SRC_DIR)/img/*.*)
|
||||
DOXYFILES := doxygen.cfg.in doxygen.intro
|
||||
|
||||
.PHONY: install-html install-doxygen doxygen generated
|
||||
|
||||
install_targets :=
|
||||
ifndef ONLY_MAN_DOCS
|
||||
install_targets += install-html
|
||||
endif
|
||||
ifeq ($(ENABLE_DOXYGEN),1)
|
||||
install_targets += install-doxygen
|
||||
endif
|
||||
install-local:: $(install_targets)
|
||||
|
||||
# Live documentation is generated for the web site using this target:
|
||||
# 'make generated BUILD_FOR_WEBSITE=1'
|
||||
generated:: doxygen
|
||||
|
||||
install-html: $(PROJ_OBJ_DIR)/html.tar.gz
|
||||
$(Echo) Installing HTML documentation
|
||||
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html
|
||||
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/img
|
||||
$(Verb) $(DataInstall) $(HTML) $(DESTDIR)$(PROJ_docsdir)/html
|
||||
# $(Verb) $(DataInstall) $(IMAGES) $(DESTDIR)$(PROJ_docsdir)/html/img
|
||||
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(DESTDIR)$(PROJ_docsdir)
|
||||
|
||||
$(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
|
||||
$(Echo) Packaging HTML documentation
|
||||
$(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/html.tar
|
||||
$(Verb) cd $(PROJ_SRC_DIR) && \
|
||||
$(TAR) cf $(PROJ_OBJ_DIR)/html.tar *.html
|
||||
$(Verb) $(GZIPBIN) $(PROJ_OBJ_DIR)/html.tar
|
||||
|
||||
install-doxygen: doxygen
|
||||
$(Echo) Installing doxygen documentation
|
||||
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(DESTDIR)$(PROJ_docsdir)
|
||||
$(Verb) cd $(PROJ_OBJ_DIR)/doxygen/html && \
|
||||
for DIR in $$($(FIND) . -type d); do \
|
||||
DESTSUB="$(DESTDIR)$(PROJ_docsdir)/html/doxygen/$$(echo $$DIR | cut -c 3-)"; \
|
||||
$(MKDIR) $$DESTSUB && \
|
||||
$(FIND) $$DIR -maxdepth 1 -type f -exec $(DataInstall) {} $$DESTSUB \; ; \
|
||||
if [ $$? != 0 ]; then exit 1; fi \
|
||||
done
|
||||
|
||||
doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz
|
||||
|
||||
regendoc:
|
||||
$(Echo) Building doxygen documentation
|
||||
$(Verb) $(RM) -rf $(PROJ_OBJ_DIR)/doxygen
|
||||
$(Verb) $(DOXYGEN) $(PROJ_OBJ_DIR)/doxygen.cfg
|
||||
$(Verb) sed -i "s/[$$]LatestRev[$$]/`svnversion $(PROJ_SRC_DIR)`/g" \
|
||||
$(PROJ_OBJ_DIR)/doxygen/html/*.html
|
||||
|
||||
$(PROJ_OBJ_DIR)/doxygen.tar.gz: $(DOXYFILES) $(PROJ_OBJ_DIR)/doxygen.cfg
|
||||
$(Echo) Packaging doxygen documentation
|
||||
$(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/doxygen.tar
|
||||
$(Verb) $(TAR) cf $(PROJ_OBJ_DIR)/doxygen.tar doxygen
|
||||
$(Verb) $(GZIPBIN) $(PROJ_OBJ_DIR)/doxygen.tar
|
||||
$(Verb) $(CP) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_OBJ_DIR)/doxygen/html/
|
||||
|
||||
userloc: $(LLVM_SRC_ROOT)/docs/userloc.html
|
||||
|
||||
$(LLVM_SRC_ROOT)/docs/userloc.html:
|
||||
$(Echo) Making User LOC Table
|
||||
$(Verb) cd $(LLVM_SRC_ROOT) ; ./utils/userloc.pl -details -recurse \
|
||||
-html lib include tools runtime utils examples autoconf test > docs/userloc.html
|
||||
|
||||
uninstall-local::
|
||||
$(Echo) Uninstalling Documentation
|
||||
$(Verb) $(RM) -rf $(DESTDIR)$(PROJ_docsdir)
|
||||
|
|
@ -171,6 +171,8 @@ Handling external code
|
|||
MemorySanitizer requires that all program code is instrumented. This
|
||||
also includes any libraries that the program depends on, even libc.
|
||||
Failing to achieve this may result in false reports.
|
||||
For the same reason you may need to replace all inline assembly code that writes to memory
|
||||
with a pure C/C++ code.
|
||||
|
||||
Full MemorySanitizer instrumentation is very difficult to achieve. To
|
||||
make it easier, MemorySanitizer runtime library includes 70+
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Using Precompiled Headers with ``clang``
|
|||
The Clang compiler frontend, ``clang -cc1``, supports two command line options
|
||||
for generating and using PCH files.
|
||||
|
||||
To generate PCH files using ``clang -cc1``, use the option :option:`-emit-pch`:
|
||||
To generate PCH files using ``clang -cc1``, use the option `-emit-pch`:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ To generate PCH files using ``clang -cc1``, use the option :option:`-emit-pch`:
|
|||
This option is transparently used by ``clang`` when generating PCH files. The
|
||||
resulting PCH file contains the serialized form of the compiler's internal
|
||||
representation after it has completed parsing and semantic analysis. The PCH
|
||||
file can then be used as a prefix header with the :option:`-include-pch`
|
||||
file can then be used as a prefix header with the `-include-pch`
|
||||
option:
|
||||
|
||||
.. code-block:: bash
|
||||
|
|
@ -84,7 +84,7 @@ With this approach, the cost of using an AST file for a translation unit is
|
|||
proportional to the amount of code actually used from the AST file, rather than
|
||||
being proportional to the size of the AST file itself.
|
||||
|
||||
When given the :option:`-print-stats` option, Clang produces statistics
|
||||
When given the `-print-stats` option, Clang produces statistics
|
||||
describing how much of the AST file was actually loaded from disk. For a
|
||||
simple "Hello, World!" program that includes the Apple ``Cocoa.h`` header
|
||||
(which is built as a precompiled header), this option illustrates how little of
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
=======================
|
||||
Clang 3.8 Release Notes
|
||||
=======================
|
||||
=====================================
|
||||
Clang 3.9 (In-Progress) Release Notes
|
||||
=====================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
|
@ -8,15 +8,21 @@ Clang 3.8 Release Notes
|
|||
|
||||
Written by the `LLVM Team <http://llvm.org/>`_
|
||||
|
||||
.. warning::
|
||||
|
||||
These are in-progress notes for the upcoming Clang 3.9 release. You may
|
||||
prefer the `Clang 3.8 Release Notes
|
||||
<http://llvm.org/releases/3.8.0/tools/clang/docs/ReleaseNotes.html>`_.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document contains the release notes for the Clang C/C++/Objective-C
|
||||
frontend, part of the LLVM Compiler Infrastructure, release 3.8. Here we
|
||||
frontend, part of the LLVM Compiler Infrastructure, release 3.9. 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
|
||||
documentation <../../../docs/ReleaseNotes.html>`_. All LLVM
|
||||
documentation <http://llvm.org/docs/ReleaseNotes.html>`_. All LLVM
|
||||
releases may be downloaded from the `LLVM releases web
|
||||
site <http://llvm.org/releases/>`_.
|
||||
|
||||
|
|
@ -25,7 +31,12 @@ the latest release, please check out the main please see the `Clang Web
|
|||
Site <http://clang.llvm.org>`_ or the `LLVM Web
|
||||
Site <http://llvm.org>`_.
|
||||
|
||||
What's New in Clang 3.8?
|
||||
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 <http://llvm.org/releases/>`_.
|
||||
|
||||
What's New in Clang 3.9?
|
||||
========================
|
||||
|
||||
Some of the major new features and improvements to Clang are listed
|
||||
|
|
@ -33,230 +44,207 @@ here. Generic improvements to Clang as a whole or to its underlying
|
|||
infrastructure are described first, followed by language-specific
|
||||
sections with improvements to Clang's support for those languages.
|
||||
|
||||
Major New Features
|
||||
------------------
|
||||
|
||||
- Clang will no longer passes --build-id by default to the linker. In modern
|
||||
linkers that is a relatively expensive option. It can be passed explicitly
|
||||
with -Wl,--build-id. To have clang always pass it, build clang with
|
||||
-DENABLE_LINKER_BUILD_ID.
|
||||
- On Itanium ABI targets, attribute abi_tag is now supported for compatibility
|
||||
with GCC. Clang implementation of abi_tag is mostly compatible with GCC ABI
|
||||
version 10.
|
||||
|
||||
Improvements to Clang's diagnostics
|
||||
-----------------------------------
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Clang's diagnostics are constantly being improved to catch more issues,
|
||||
explain them more clearly, and provide more accurate source information
|
||||
about them. The improvements since the 3.7 release include:
|
||||
about them. The improvements since the 3.8 release include:
|
||||
|
||||
- ``-Wmicrosoft`` has been split into many targeted flags, so that projects can
|
||||
choose to enable only a subset of these warnings. ``-Wno-microsoft`` still
|
||||
disables all these warnings, and ``-Wmicrosoft`` still enables them all.
|
||||
- ...
|
||||
|
||||
New Compiler Flags
|
||||
------------------
|
||||
|
||||
Clang can "tune" DWARF debugging information to suit one of several different
|
||||
debuggers. This fine-tuning can mean omitting DWARF features that the
|
||||
debugger does not need or use, or including DWARF extensions specific to the
|
||||
debugger. Clang supports tuning for three debuggers, as follows.
|
||||
The option ....
|
||||
|
||||
- ``-ggdb`` is equivalent to ``-g`` plus tuning for the GDB debugger. For
|
||||
compatibility with GCC, Clang allows this option to be followed by a
|
||||
single digit from 0 to 3 indicating the debugging information "level."
|
||||
For example, ``-ggdb1`` is equivalent to ``-ggdb -g1``.
|
||||
|
||||
- ``-glldb`` is equivalent to ``-g`` plus tuning for the LLDB debugger.
|
||||
New Pragmas in Clang
|
||||
-----------------------
|
||||
|
||||
- ``-gsce`` is equivalent to ``-g`` plus tuning for the Sony Computer
|
||||
Entertainment debugger.
|
||||
Clang now supports the ...
|
||||
|
||||
Specifying ``-g`` without a tuning option will use a target-dependent default.
|
||||
|
||||
The new ``-fstrict-vtable-pointers`` flag enables better devirtualization
|
||||
support (experimental).
|
||||
Attribute Changes in Clang
|
||||
--------------------------
|
||||
|
||||
- The ``nodebug`` attribute may now be applied to static, global, and local
|
||||
variables (but not parameters or non-static data members). This will suppress
|
||||
all debugging information for the variable (and its type, if there are no
|
||||
other uses of the type).
|
||||
|
||||
|
||||
Windows Support
|
||||
---------------
|
||||
|
||||
Clang's support for building native Windows programs ...
|
||||
|
||||
TLS is enabled for Cygwin defaults to -femulated-tls.
|
||||
|
||||
|
||||
C Language Changes in Clang
|
||||
---------------------------
|
||||
The -faltivec and -maltivec flags no longer silently include altivec.h on Power platforms.
|
||||
|
||||
Better support for ``__builtin_object_size``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
`RenderScript
|
||||
<https://developer.android.com/guide/topics/renderscript/compute.html>`_
|
||||
support added to the Frontend and enabled by the '-x renderscript' option or
|
||||
the '.rs' file extension.
|
||||
|
||||
Clang 3.8 has expanded support for the ``__builtin_object_size`` intrinsic.
|
||||
Specifically, ``__builtin_object_size`` will now fail less often when you're
|
||||
trying to get the size of a subobject. Additionally, the ``pass_object_size``
|
||||
attribute was added, which allows ``__builtin_object_size`` to successfully
|
||||
report the size of function parameters, without requiring that the function be
|
||||
inlined.
|
||||
...
|
||||
|
||||
C11 Feature Support
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``overloadable`` attribute relaxations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
|
||||
Previously, functions marked ``overloadable`` in C would strictly use C++'s
|
||||
type conversion rules, so the following code would not compile:
|
||||
C++ Language Changes in Clang
|
||||
-----------------------------
|
||||
|
||||
.. code-block:: c
|
||||
- Clang now enforces the rule that a *using-declaration* cannot name an enumerator of a
|
||||
scoped enumeration.
|
||||
|
||||
void foo(char *bar, char *baz) __attribute__((overloadable));
|
||||
void foo(char *bar) __attribute__((overloadable));
|
||||
.. code-block:: c++
|
||||
|
||||
void callFoo() {
|
||||
int a;
|
||||
foo(&a);
|
||||
}
|
||||
namespace Foo { enum class E { e }; }
|
||||
namespace Bar {
|
||||
using Foo::E::e; // error
|
||||
constexpr auto e = Foo::E::e; // ok
|
||||
}
|
||||
|
||||
Now, Clang is able to selectively use C's type conversion rules during overload
|
||||
resolution in C, which allows the above example to compile (albeit potentially
|
||||
with a warning about an implicit conversion from ``int*`` to ``char*``).
|
||||
- Clang now enforces the rule that an enumerator of an unscoped enumeration declared at
|
||||
class scope can only be named by a *using-declaration* in a derived class.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
class Foo { enum E { e }; }
|
||||
using Foo::e; // error
|
||||
static constexpr auto e = Foo::e; // ok
|
||||
|
||||
...
|
||||
|
||||
C++1z Feature Support
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Clang's experimental support for the upcoming C++1z standard can be enabled with ``-std=c++1z``.
|
||||
Changes to C++1z features since Clang 3.8:
|
||||
|
||||
- The ``[[fallthrough]]``, ``[[nodiscard]]``, and ``[[maybe_unused]]`` attributes are
|
||||
supported in C++11 onwards, and are largely synonymous with Clang's existing attributes
|
||||
``[[clang::fallthrough]]``, ``[[gnu::warn_unused_result]]``, and ``[[gnu::unused]]``.
|
||||
Use ``-Wimplicit-fallthrough`` to warn on unannotated fallthrough within ``switch``
|
||||
statements.
|
||||
|
||||
- In C++1z mode, aggregate initialization can be performed for classes with base classes:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
struct A { int n; };
|
||||
struct B : A { int x, y; };
|
||||
B b = { 1, 2, 3 }; // b.n == 1, b.x == 2, b.y == 3
|
||||
|
||||
- The range in a range-based ``for`` statement can have different types for its ``begin``
|
||||
and ``end`` iterators. This is permitted as an extension in C++11 onwards.
|
||||
|
||||
- Lambda-expressions can explicitly capture ``*this`` (to capture the surrounding object
|
||||
by copy). This is permitted as an extension in C++11 onwards.
|
||||
|
||||
- Objects of enumeration type can be direct-list-initialized from a value of the underlying
|
||||
type. ``E{n}`` is equivalent to ``E(n)``, except that it implies a check for a narrowing
|
||||
conversion.
|
||||
|
||||
- Unary *fold-expression*\s over an empty pack are now rejected for all operators
|
||||
other than ``&&``, ``||``, and ``,``.
|
||||
|
||||
...
|
||||
|
||||
Objective-C Language Changes in Clang
|
||||
-------------------------------------
|
||||
|
||||
...
|
||||
|
||||
OpenCL C Language Changes in Clang
|
||||
----------------------------------
|
||||
|
||||
Several OpenCL 2.0 features have been added, including:
|
||||
|
||||
- Command-line option ``-std=CL2.0``.
|
||||
|
||||
- Generic address space (``__generic``) along with new conversion rules
|
||||
between different address spaces and default address space deduction.
|
||||
|
||||
- Support for program scope variables with ``__global`` address space.
|
||||
|
||||
- Pipe specifier was added (although no pipe functions are supported yet).
|
||||
|
||||
- Atomic types: ``atomic_int``, ``atomic_uint``, ``atomic_long``,
|
||||
``atomic_ulong``, ``atomic_float``, ``atomic_double``, ``atomic_flag``,
|
||||
``atomic_intptr_t``, ``atomic_uintptr_t``, ``atomic_size_t``,
|
||||
``atomic_ptrdiff_t`` and their usage with C11 style builtin functions.
|
||||
|
||||
- Image types: ``image2d_depth_t``, ``image2d_array_depth_t``,
|
||||
``image2d_msaa_t``, ``image2d_array_msaa_t``, ``image2d_msaa_depth_t``,
|
||||
``image2d_array_msaa_depth_t``.
|
||||
|
||||
- Other types (for pipes and device side enqueue): ``clk_event_t``,
|
||||
``queue_t``, ``ndrange_t``, ``reserve_id_t``.
|
||||
|
||||
Several additional features/bugfixes have been added to the previous standards:
|
||||
|
||||
- A set of floating point arithmetic relaxation flags: ``-cl-no-signed-zeros``,
|
||||
``-cl-unsafe-math-optimizations``, ``-cl-finite-math-only``,
|
||||
``-cl-fast-relaxed-math``.
|
||||
|
||||
- Added ``^^`` to the list of reserved operations.
|
||||
|
||||
- Improved vector support and diagnostics.
|
||||
|
||||
- Improved diagnostics for function pointers.
|
||||
...
|
||||
|
||||
OpenMP Support in Clang
|
||||
-----------------------
|
||||
----------------------------------
|
||||
|
||||
OpenMP 3.1 is fully supported and is enabled by default with ``-fopenmp``
|
||||
which now uses the Clang OpenMP library instead of the GCC OpenMP library.
|
||||
The runtime can be built in-tree.
|
||||
Added support for all non-offloading features from OpenMP 4.5, including using
|
||||
data members in private clauses of non-static member functions. Additionally,
|
||||
data members can be used as loop control variables in loop-based directives.
|
||||
|
||||
In addition to OpenMP 3.1, several important elements of the OpenMP 4.0/4.5
|
||||
are supported as well. We continue to aim to complete OpenMP 4.5
|
||||
Currently Clang supports OpenMP 3.1 and all non-offloading features of
|
||||
OpenMP 4.0/4.5. Offloading features are under development. Clang defines macro
|
||||
_OPENMP and sets it to OpenMP 3.1 (in accordance with OpenMP standard) by
|
||||
default. User may change this value using ``-fopenmp-version=[31|40|45]`` option.
|
||||
|
||||
- ``map`` clause
|
||||
- task dependencies
|
||||
- ``num_teams`` clause
|
||||
- ``thread_limit`` clause
|
||||
- ``target`` and ``target data`` directive
|
||||
- ``target`` directive with implicit data mapping
|
||||
- ``target enter data`` and ``target exit data`` directive
|
||||
- Array sections [2.4, Array Sections].
|
||||
- Directive name modifiers for ``if`` clause [2.12, if Clause].
|
||||
- ``linear`` clause can be used in loop-based directives [2.7.2, loop Construct].
|
||||
- ``simdlen`` clause [2.8, SIMD Construct].
|
||||
- ``hint`` clause [2.13.2, critical Construct].
|
||||
- Parsing/semantic analysis of all non-device directives introduced in OpenMP 4.5.
|
||||
|
||||
The codegen for OpenMP constructs was significantly improved allowing us to produce much more stable and fast code.
|
||||
Full test cases of IR are also implemented.
|
||||
|
||||
CUDA Support in Clang
|
||||
---------------------
|
||||
Clang has experimental support for end-to-end CUDA compilation now:
|
||||
|
||||
- The driver now detects CUDA installation, creates host and device compilation
|
||||
pipelines, links device-side code with appropriate CUDA bitcode and produces
|
||||
single object file with host and GPU code.
|
||||
|
||||
- Implemented target attribute-based function overloading which allows Clang to
|
||||
compile CUDA sources without splitting them into separate host/device TUs.
|
||||
The codegen for OpenMP constructs was significantly improved to produce much
|
||||
more stable and faster code.
|
||||
|
||||
Internal API Changes
|
||||
--------------------
|
||||
|
||||
These are major API changes that have happened since the 3.7 release of
|
||||
These are major API changes that have happened since the 3.8 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.
|
||||
|
||||
* With this release, the autoconf build system is deprecated. It will be removed
|
||||
in the 3.9 release. Please migrate to using CMake. For more information see:
|
||||
`Building LLVM with CMake <http://llvm.org/docs/CMake.html>`_
|
||||
- ...
|
||||
|
||||
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
|
||||
======================= ============================
|
||||
- has and hasAnyArgument: Matchers no longer ignores parentheses and implicit
|
||||
casts on the argument before applying the inner matcher. The fix was done to
|
||||
allow for greater control by the user. In all existing checkers that use this
|
||||
matcher all instances of code ``hasAnyArgument(<inner matcher>)`` or
|
||||
``has(<inner matcher>)`` must be changed to
|
||||
``hasAnyArgument(ignoringParenImpCasts(<inner matcher>))`` or
|
||||
``has(ignoringParenImpCasts(<inner matcher>))``.
|
||||
|
||||
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 scan-build and scan-view tools will now be installed with Clang. Use these
|
||||
tools to run the static analyzer on projects and view the produced results.
|
||||
...
|
||||
|
||||
Static analysis of C++ lambdas has been greatly improved, including
|
||||
interprocedural analysis of lambda applications.
|
||||
Core Analysis Improvements
|
||||
==========================
|
||||
|
||||
Several new checks were added:
|
||||
- ...
|
||||
|
||||
- The analyzer now checks for misuse of ``vfork()``.
|
||||
- The analyzer can now detect excessively-padded structs. This check can be
|
||||
enabled by passing the following command to scan-build:
|
||||
``-enable-checker optin.performance.Padding``.
|
||||
- The checks to detect misuse of ``_Nonnull`` type qualifiers as well as checks
|
||||
to detect misuse of Objective-C generics were added.
|
||||
- The analyzer now has opt in checks to detect localization errors in Cocoa
|
||||
applications. The checks warn about uses of non-localized ``NSStrings``
|
||||
passed to UI methods expecting localized strings and on ``NSLocalizedString``
|
||||
macros that are missing the comment argument. These can be enabled by passing
|
||||
the following command to scan-build:
|
||||
``-enable-checker optin.osx.cocoa.localizability``.
|
||||
New Issues Found
|
||||
================
|
||||
|
||||
- ...
|
||||
|
||||
Python Binding Changes
|
||||
----------------------
|
||||
|
||||
The following methods have been added:
|
||||
|
||||
- ...
|
||||
|
||||
Significant Known Problems
|
||||
==========================
|
||||
|
||||
Additional Information
|
||||
======================
|
||||
|
|
|
|||
|
|
@ -178,6 +178,17 @@ Please refer to the `Code-Pointer Integrity <http://dslab.epfl.ch/proj/cpi/>`__
|
|||
project page for more information about the design of the SafeStack and its
|
||||
related technologies.
|
||||
|
||||
setjmp and exception handling
|
||||
-----------------------------
|
||||
|
||||
The `OSDI'14 paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
|
||||
on Linux the instrumentation pass finds calls to setjmp or functions that
|
||||
may throw an exception, and inserts required instrumentation at their call
|
||||
sites. Specifically, the instrumentation pass saves the shadow stack pointer
|
||||
on the safe stack before the call site, and restores it either after the
|
||||
call to setjmp or after an exception has been caught. This is implemented
|
||||
in the function ``SafeStack::createStackRestorePoints``.
|
||||
|
||||
Publications
|
||||
------------
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ How to build and run
|
|||
====================
|
||||
|
||||
SanitizerCoverage can be used with :doc:`AddressSanitizer`,
|
||||
:doc:`LeakSanitizer`, :doc:`MemorySanitizer`, and UndefinedBehaviorSanitizer.
|
||||
In addition to ``-fsanitize=``, pass one of the following compile-time flags:
|
||||
:doc:`LeakSanitizer`, :doc:`MemorySanitizer`,
|
||||
UndefinedBehaviorSanitizer, or without any sanitizer. Pass one of the
|
||||
following compile-time flags:
|
||||
|
||||
* ``-fsanitize-coverage=func`` for function-level coverage (very fast).
|
||||
* ``-fsanitize-coverage=bb`` for basic-block-level coverage (may add up to 30%
|
||||
|
|
@ -27,8 +28,9 @@ In addition to ``-fsanitize=``, pass one of the following compile-time flags:
|
|||
You may also specify ``-fsanitize-coverage=indirect-calls`` for
|
||||
additional `caller-callee coverage`_.
|
||||
|
||||
At run time, pass ``coverage=1`` in ``ASAN_OPTIONS``, ``LSAN_OPTIONS``,
|
||||
``MSAN_OPTIONS`` or ``UBSAN_OPTIONS``, as appropriate.
|
||||
At run time, pass ``coverage=1`` in ``ASAN_OPTIONS``,
|
||||
``LSAN_OPTIONS``, ``MSAN_OPTIONS`` or ``UBSAN_OPTIONS``, as
|
||||
appropriate. For the standalone coverage mode, use ``UBSAN_OPTIONS``.
|
||||
|
||||
To get `Coverage counters`_, add ``-fsanitize-coverage=8bit-counters``
|
||||
to one of the above compile-time flags. At runtime, use
|
||||
|
|
@ -94,6 +96,41 @@ numbers:
|
|||
cov.cc:3
|
||||
cov.cc:5
|
||||
|
||||
Sancov Tool
|
||||
===========
|
||||
|
||||
A new experimental ``sancov`` tool is developed to process coverage files.
|
||||
The tool is part of LLVM project and is currently supported only on Linux.
|
||||
It can handle symbolization tasks autonomously without any extra support
|
||||
from the environment. You need to pass .sancov files (named
|
||||
``<module_name>.<pid>.sancov`` and paths to all corresponding binary elf files.
|
||||
Sancov matches these files using module names and binaries file names.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
USAGE: sancov [options] <action> (<binary file>|<.sancov file>)...
|
||||
|
||||
Action (required)
|
||||
-print - Print coverage addresses
|
||||
-covered-functions - Print all covered functions.
|
||||
-not-covered-functions - Print all not covered functions.
|
||||
-html-report - Print HTML coverage report.
|
||||
|
||||
Options
|
||||
-blacklist=<string> - Blacklist file (sanitizer blacklist format).
|
||||
-demangle - Print demangled function name.
|
||||
-strip_path_prefix=<string> - Strip this prefix from file paths in reports
|
||||
|
||||
|
||||
Automatic HTML Report Generation
|
||||
================================
|
||||
|
||||
If ``*SAN_OPTIONS`` contains ``html_cov_report=1`` option set, then html
|
||||
coverage report would be automatically generated alongside the coverage files.
|
||||
The ``sancov`` binary should be present in ``PATH`` or
|
||||
``sancov_path=<path_to_sancov`` option can be used to specify tool location.
|
||||
|
||||
|
||||
How good is the coverage?
|
||||
=========================
|
||||
|
||||
|
|
@ -209,7 +246,7 @@ Coverage counters
|
|||
=================
|
||||
|
||||
This experimental feature is inspired by
|
||||
`AFL <http://lcamtuf.coredump.cx/afl/technical_details.txt>`_'s coverage
|
||||
`AFL <http://lcamtuf.coredump.cx/afl/technical_details.txt>`__'s coverage
|
||||
instrumentation. With additional compile-time and run-time flags you can get
|
||||
more sensitive coverage information. In addition to boolean values assigned to
|
||||
every basic block (edge) the instrumentation will collect imprecise counters.
|
||||
|
|
@ -251,10 +288,38 @@ These counters may also be used for in-process coverage-guided fuzzers. See
|
|||
|
||||
Tracing basic blocks
|
||||
====================
|
||||
An *experimental* feature to support basic block (or edge) tracing.
|
||||
Experimental support for basic block (or edge) tracing.
|
||||
With ``-fsanitize-coverage=trace-bb`` the compiler will insert
|
||||
``__sanitizer_cov_trace_basic_block(s32 *id)`` before every function, basic block, or edge
|
||||
(depending on the value of ``-fsanitize-coverage=[func,bb,edge]``).
|
||||
Example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% clang -g -fsanitize=address -fsanitize-coverage=edge,trace-bb foo.cc
|
||||
% ASAN_OPTIONS=coverage=1 ./a.out
|
||||
|
||||
This will produce two files after the process exit:
|
||||
`trace-points.PID.sancov` and `trace-events.PID.sancov`.
|
||||
The first file will contain a textual description of all the instrumented points in the program
|
||||
in the form that you can feed into llvm-symbolizer (e.g. `a.out 0x4dca89`), one per line.
|
||||
The second file will contain the actual execution trace as a sequence of 4-byte integers
|
||||
-- these integers are the indices into the array of instrumented points (the first file).
|
||||
|
||||
Basic block tracing is currently supported only for single-threaded applications.
|
||||
|
||||
|
||||
Tracing PCs
|
||||
===========
|
||||
*Experimental* feature similar to tracing basic blocks, but with a different API.
|
||||
With ``-fsanitize-coverage=trace-pc`` the compiler will insert
|
||||
``__sanitizer_cov_trace_pc()`` on every edge.
|
||||
With an additional ``...=trace-pc,indirect-calls`` flag
|
||||
``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.
|
||||
These callbacks are not implemented in the Sanitizer run-time and should be defined
|
||||
by the user. So, these flags do not require the other sanitizer to be used.
|
||||
This mechanism is used for fuzzing the Linux kernel (https://github.com/google/syzkaller)
|
||||
and can be used with `AFL <http://lcamtuf.coredump.cx/afl>`__.
|
||||
|
||||
Tracing data flow
|
||||
=================
|
||||
|
|
|
|||
62
docs/SanitizerStats.rst
Normal file
62
docs/SanitizerStats.rst
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
==============
|
||||
SanitizerStats
|
||||
==============
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The sanitizers support a simple mechanism for gathering profiling statistics
|
||||
to help understand the overhead associated with sanitizers.
|
||||
|
||||
How to build and run
|
||||
====================
|
||||
|
||||
SanitizerStats can currently only be used with :doc:`ControlFlowIntegrity`.
|
||||
In addition to ``-fsanitize=cfi*``, pass the ``-fsanitize-stats`` flag.
|
||||
This will cause the program to count the number of times that each control
|
||||
flow integrity check in the program fires.
|
||||
|
||||
At run time, set the ``SANITIZER_STATS_PATH`` environment variable to direct
|
||||
statistics output to a file. The file will be written on process exit.
|
||||
The following substitutions will be applied to the environment variable:
|
||||
|
||||
- ``%b`` -- The executable basename.
|
||||
- ``%p`` -- The process ID.
|
||||
|
||||
You can also send the ``SIGUSR2`` signal to a process to make it write
|
||||
sanitizer statistics immediately.
|
||||
|
||||
The ``sanstats`` program can be used to dump statistics. It takes as a
|
||||
command line argument the path to a statistics file produced by a program
|
||||
compiled with ``-fsanitize-stats``.
|
||||
|
||||
The output of ``sanstats`` is in four columns, separated by spaces. The first
|
||||
column is the file and line number of the call site. The second column is
|
||||
the function name. The third column is the type of statistic gathered (in
|
||||
this case, the type of control flow integrity check). The fourth column is
|
||||
the call count.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cat -n vcall.cc
|
||||
1 struct A {
|
||||
2 virtual void f() {}
|
||||
3 };
|
||||
4
|
||||
5 __attribute__((noinline)) void g(A *a) {
|
||||
6 a->f();
|
||||
7 }
|
||||
8
|
||||
9 int main() {
|
||||
10 A a;
|
||||
11 g(&a);
|
||||
12 }
|
||||
$ clang++ -fsanitize=cfi -flto -fuse-ld=gold vcall.cc -fsanitize-stats -g
|
||||
$ SANITIZER_STATS_PATH=a.stats ./a.out
|
||||
$ sanstats a.stats
|
||||
vcall.cc:6 _Z1gP1A cfi-vcall 1
|
||||
237
docs/SourceBasedCodeCoverage.rst
Normal file
237
docs/SourceBasedCodeCoverage.rst
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
==========================
|
||||
Source-based Code Coverage
|
||||
==========================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document explains how to use clang's source-based code coverage feature.
|
||||
It's called "source-based" because it operates on AST and preprocessor
|
||||
information directly. This allows it to generate very precise coverage data.
|
||||
|
||||
Clang ships two other code coverage implementations:
|
||||
|
||||
* :doc:`SanitizerCoverage` - A low-overhead tool meant for use alongside the
|
||||
various sanitizers. It can provide up to edge-level coverage.
|
||||
|
||||
* gcov - A GCC-compatible coverage implementation which operates on DebugInfo.
|
||||
|
||||
From this point onwards "code coverage" will refer to the source-based kind.
|
||||
|
||||
The code coverage workflow
|
||||
==========================
|
||||
|
||||
The code coverage workflow consists of three main steps:
|
||||
|
||||
* Compiling with coverage enabled.
|
||||
|
||||
* Running the instrumented program.
|
||||
|
||||
* Creating coverage reports.
|
||||
|
||||
The next few sections work through a complete, copy-'n-paste friendly example
|
||||
based on this program:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
% cat <<EOF > foo.cc
|
||||
#define BAR(x) ((x) || (x))
|
||||
template <typename T> void foo(T x) {
|
||||
for (unsigned I = 0; I < 10; ++I) { BAR(I); }
|
||||
}
|
||||
int main() {
|
||||
foo<int>(0);
|
||||
foo<float>(0);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
Compiling with coverage enabled
|
||||
===============================
|
||||
|
||||
To compile code with coverage enabled, pass ``-fprofile-instr-generate
|
||||
-fcoverage-mapping`` to the compiler:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# Step 1: Compile with coverage enabled.
|
||||
% clang++ -fprofile-instr-generate -fcoverage-mapping foo.cc -o foo
|
||||
|
||||
Note that linking together code with and without coverage instrumentation is
|
||||
supported: any uninstrumented code simply won't be accounted for.
|
||||
|
||||
Running the instrumented program
|
||||
================================
|
||||
|
||||
The next step is to run the instrumented program. When the program exits it
|
||||
will write a **raw profile** to the path specified by the ``LLVM_PROFILE_FILE``
|
||||
environment variable. If that variable does not exist, the profile is written
|
||||
to ``default.profraw`` in the current directory of the program. If
|
||||
``LLVM_PROFILE_FILE`` contains a path to a non-existent directory, the missing
|
||||
directory structure will be created. Additionally, the following special
|
||||
**pattern strings** are rewritten:
|
||||
|
||||
* "%p" expands out to the process ID.
|
||||
|
||||
* "%h" expands out to the hostname of the machine running the program.
|
||||
|
||||
* "%Nm" expands out to the instrumented binary's signature. When this pattern
|
||||
is specified, the runtime creates a pool of N raw profiles which are used for
|
||||
on-line profile merging. The runtime takes care of selecting a raw profile
|
||||
from the pool, locking it, and updating it before the program exits. If N is
|
||||
not specified (i.e the pattern is "%m"), it's assumed that ``N = 1``. N must
|
||||
be between 1 and 9. The merge pool specifier can only occur once per filename
|
||||
pattern.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# Step 2: Run the program.
|
||||
% LLVM_PROFILE_FILE="foo.profraw" ./foo
|
||||
|
||||
Creating coverage reports
|
||||
=========================
|
||||
|
||||
Raw profiles have to be **indexed** before they can be used to generate
|
||||
coverage reports. This is done using the "merge" tool in ``llvm-profdata``, so
|
||||
named because it can combine and index profiles at the same time:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# Step 3(a): Index the raw profile.
|
||||
% llvm-profdata merge -sparse foo.profraw -o foo.profdata
|
||||
|
||||
There are multiple different ways to render coverage reports. One option is to
|
||||
generate a line-oriented report:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# Step 3(b): Create a line-oriented coverage report.
|
||||
% llvm-cov show ./foo -instr-profile=foo.profdata
|
||||
|
||||
To demangle any C++ identifiers in the output, use:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% llvm-cov show ./foo -instr-profile=foo.profdata | c++filt -n
|
||||
|
||||
This report includes a summary view as well as dedicated sub-views for
|
||||
templated functions and their instantiations. For our example program, we get
|
||||
distinct views for ``foo<int>(...)`` and ``foo<float>(...)``. If
|
||||
``-show-line-counts-or-regions`` is enabled, ``llvm-cov`` displays sub-line
|
||||
region counts (even in macro expansions):
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
20| 1|#define BAR(x) ((x) || (x))
|
||||
^20 ^2
|
||||
2| 2|template <typename T> void foo(T x) {
|
||||
22| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
|
||||
^22 ^20 ^20^20
|
||||
2| 4|}
|
||||
------------------
|
||||
| void foo<int>(int):
|
||||
| 1| 2|template <typename T> void foo(T x) {
|
||||
| 11| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
|
||||
| ^11 ^10 ^10^10
|
||||
| 1| 4|}
|
||||
------------------
|
||||
| void foo<float>(int):
|
||||
| 1| 2|template <typename T> void foo(T x) {
|
||||
| 11| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
|
||||
| ^11 ^10 ^10^10
|
||||
| 1| 4|}
|
||||
------------------
|
||||
|
||||
It's possible to generate a file-level summary of coverage statistics (instead
|
||||
of a line-oriented report) with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# Step 3(c): Create a coverage summary.
|
||||
% llvm-cov report ./foo -instr-profile=foo.profdata
|
||||
Filename Regions Miss Cover Functions Executed
|
||||
-----------------------------------------------------------------------
|
||||
/tmp/foo.cc 13 0 100.00% 3 100.00%
|
||||
-----------------------------------------------------------------------
|
||||
TOTAL 13 0 100.00% 3 100.00%
|
||||
|
||||
A few final notes:
|
||||
|
||||
* The ``-sparse`` flag is optional but can result in dramatically smaller
|
||||
indexed profiles. This option should not be used if the indexed profile will
|
||||
be reused for PGO.
|
||||
|
||||
* Raw profiles can be discarded after they are indexed. Advanced use of the
|
||||
profile runtime library allows an instrumented program to merge profiling
|
||||
information directly into an existing raw profile on disk. The details are
|
||||
out of scope.
|
||||
|
||||
* The ``llvm-profdata`` tool can be used to merge together multiple raw or
|
||||
indexed profiles. To combine profiling data from multiple runs of a program,
|
||||
try e.g:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% llvm-profdata merge -sparse foo1.profraw foo2.profdata -o foo3.profdata
|
||||
|
||||
Format compatibility guarantees
|
||||
===============================
|
||||
|
||||
* There are no backwards or forwards compatibility guarantees for the raw
|
||||
profile format. Raw profiles may be dependent on the specific compiler
|
||||
revision used to generate them. It's inadvisable to store raw profiles for
|
||||
long periods of time.
|
||||
|
||||
* Tools must retain **backwards** compatibility with indexed profile formats.
|
||||
These formats are not forwards-compatible: i.e, a tool which uses format
|
||||
version X will not be able to understand format version (X+k).
|
||||
|
||||
* There is a third format in play: the format of the coverage mappings emitted
|
||||
into instrumented binaries. Tools must retain **backwards** compatibility
|
||||
with these formats. These formats are not forwards-compatible.
|
||||
|
||||
Using the profiling runtime without static initializers
|
||||
=======================================================
|
||||
|
||||
By default the compiler runtime uses a static initializer to determine the
|
||||
profile output path and to register a writer function. To collect profiles
|
||||
without using static initializers, do this manually:
|
||||
|
||||
* Export a ``int __llvm_profile_runtime`` symbol from each instrumented shared
|
||||
library and executable. When the linker finds a definition of this symbol, it
|
||||
knows to skip loading the object which contains the profiling runtime's
|
||||
static initializer.
|
||||
|
||||
* Forward-declare ``void __llvm_profile_initialize_file(void)`` and call it
|
||||
once from each instrumented executable. This function parses
|
||||
``LLVM_PROFILE_FILE``, sets the output path, and truncates any existing files
|
||||
at that path. To get the same behavior without truncating existing files,
|
||||
pass a filename pattern string to ``void __llvm_profile_set_filename(char
|
||||
*)``. These calls can be placed anywhere so long as they precede all calls
|
||||
to ``__llvm_profile_write_file``.
|
||||
|
||||
* Forward-declare ``int __llvm_profile_write_file(void)`` and call it to write
|
||||
out a profile. This function returns 0 when it succeeds, and a non-zero value
|
||||
otherwise. Calling this function multiple times appends profile data to an
|
||||
existing on-disk raw profile.
|
||||
|
||||
Drawbacks and limitations
|
||||
=========================
|
||||
|
||||
* Code coverage does not handle unpredictable changes in control flow or stack
|
||||
unwinding in the presence of exceptions precisely. Consider the following
|
||||
function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int f() {
|
||||
may_throw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
If the call to ``may_throw()`` propagates an exception into ``f``, the code
|
||||
coverage tool may mark the ``return`` statement as executed even though it is
|
||||
not. A call to ``longjmp()`` can have similar effects.
|
||||
|
|
@ -30,7 +30,7 @@ and line numbers in the warning messages.
|
|||
|
||||
Example:
|
||||
|
||||
.. code-block:: c++
|
||||
.. code-block:: console
|
||||
|
||||
% cat projects/compiler-rt/lib/tsan/lit_tests/tiny_race.c
|
||||
#include <pthread.h>
|
||||
|
|
|
|||
|
|
@ -92,11 +92,14 @@ Available checks are:
|
|||
parameter which is declared to never be null.
|
||||
- ``-fsanitize=null``: Use of a null pointer or creation of a null
|
||||
reference.
|
||||
- ``-fsanitize=object-size``: An attempt to use bytes which the
|
||||
optimizer can determine are not part of the object being
|
||||
accessed. The sizes of objects are determined using
|
||||
``__builtin_object_size``, and consequently may be able to detect
|
||||
more problems at higher optimization levels.
|
||||
- ``-fsanitize=object-size``: An attempt to potentially use bytes which
|
||||
the optimizer can determine are not part of the object being accessed.
|
||||
This will also detect some types of undefined behavior that may not
|
||||
directly access memory, but are provably incorrect given the size of
|
||||
the objects involved, such as invalid downcasts and calling methods on
|
||||
invalid pointers. These checks are made in terms of
|
||||
``__builtin_object_size``, and consequently may be able to detect more
|
||||
problems at higher optimization levels.
|
||||
- ``-fsanitize=return``: In C++, reaching the end of a
|
||||
value-returning function without returning a value.
|
||||
- ``-fsanitize=returns-nonnull-attribute``: Returning null pointer
|
||||
|
|
@ -225,6 +228,26 @@ UndefinedBehaviorSanitizer is available on selected platforms starting from LLVM
|
|||
3.3. The test suite is integrated into the CMake build and can be run with
|
||||
``check-ubsan`` command.
|
||||
|
||||
Additional Configuration
|
||||
========================
|
||||
|
||||
UndefinedBehaviorSanitizer adds static check data for each check unless it is
|
||||
in trap mode. This check data includes the full file name. The option
|
||||
``-fsanitize-undefined-strip-path-components=N`` can be used to trim this
|
||||
information. If ``N`` is positive, file information emitted by
|
||||
UndefinedBehaviorSanitizer will drop the first ``N`` components from the file
|
||||
path. If ``N`` is negative, the last ``N`` components will be kept.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
For a file called ``/code/library/file.cpp``, here is what would be emitted:
|
||||
* Default (No flag, or ``-fsanitize-undefined-strip-path-components=0``): ``/code/library/file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=1``: ``code/library/file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp``
|
||||
|
||||
More Information
|
||||
================
|
||||
|
||||
|
|
|
|||
|
|
@ -133,13 +133,13 @@ Options to Control Error and Warning Messages
|
|||
.. option:: -ferror-limit=123
|
||||
|
||||
Stop emitting diagnostics after 123 errors have been produced. The default is
|
||||
20, and the error limit can be disabled with :option:`-ferror-limit=0`.
|
||||
20, and the error limit can be disabled with `-ferror-limit=0`.
|
||||
|
||||
.. option:: -ftemplate-backtrace-limit=123
|
||||
|
||||
Only emit up to 123 template instantiation notes within the template
|
||||
instantiation backtrace for a single warning or error. The default is 10, and
|
||||
the limit can be disabled with :option:`-ftemplate-backtrace-limit=0`.
|
||||
the limit can be disabled with `-ftemplate-backtrace-limit=0`.
|
||||
|
||||
.. _cl_diag_formatting:
|
||||
|
||||
|
|
@ -543,15 +543,15 @@ vectorize a loop body.
|
|||
Clang offers a family of flags which the optimizers can use to emit
|
||||
a diagnostic in three cases:
|
||||
|
||||
1. When the pass makes a transformation (:option:`-Rpass`).
|
||||
1. When the pass makes a transformation (`-Rpass`).
|
||||
|
||||
2. When the pass fails to make a transformation (:option:`-Rpass-missed`).
|
||||
2. When the pass fails to make a transformation (`-Rpass-missed`).
|
||||
|
||||
3. When the pass determines whether or not to make a transformation
|
||||
(:option:`-Rpass-analysis`).
|
||||
(`-Rpass-analysis`).
|
||||
|
||||
NOTE: Although the discussion below focuses on :option:`-Rpass`, the exact
|
||||
same options apply to :option:`-Rpass-missed` and :option:`-Rpass-analysis`.
|
||||
NOTE: Although the discussion below focuses on `-Rpass`, the exact
|
||||
same options apply to `-Rpass-missed` and `-Rpass-analysis`.
|
||||
|
||||
Since there are dozens of passes inside the compiler, each of these flags
|
||||
take a regular expression that identifies the name of the pass which should
|
||||
|
|
@ -567,7 +567,7 @@ compile the code with:
|
|||
|
||||
Note that remarks from the inliner are identified with `[-Rpass=inline]`.
|
||||
To request a report from every optimization pass, you should use
|
||||
:option:`-Rpass=.*` (in fact, you can use any valid POSIX regular
|
||||
`-Rpass=.*` (in fact, you can use any valid POSIX regular
|
||||
expression). However, do not expect a report from every transformation
|
||||
made by the compiler. Optimization remarks do not really make sense
|
||||
outside of the major transformations (e.g., inlining, vectorization,
|
||||
|
|
@ -585,7 +585,7 @@ Current limitations
|
|||
2. Some source locations are not displayed correctly. The front end has
|
||||
a more detailed source location tracking than the locations included
|
||||
in the debug info (e.g., the front end can locate code inside macro
|
||||
expansions). However, the locations used by :option:`-Rpass` are
|
||||
expansions). However, the locations used by `-Rpass` are
|
||||
translated from debug annotations. That translation can be lossy,
|
||||
which results in some remarks having no location information.
|
||||
|
||||
|
|
@ -711,16 +711,19 @@ also allows you to push and pop the current warning state. This is
|
|||
particularly useful when writing a header file that will be compiled by
|
||||
other people, because you don't know what warning flags they build with.
|
||||
|
||||
In the below example :option:`-Wmultichar` is ignored for only a single line of
|
||||
code, after which the diagnostics return to whatever state had previously
|
||||
In the below example :option:`-Wextra-tokens` is ignored for only a single line
|
||||
of code, after which the diagnostics return to whatever state had previously
|
||||
existed.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wmultichar"
|
||||
#if foo
|
||||
#endif foo // warning: extra tokens at end of #endif directive
|
||||
|
||||
char b = 'df'; // no warning.
|
||||
#pragma clang diagnostic ignored "-Wextra-tokens"
|
||||
|
||||
#if foo
|
||||
#endif foo // no warning
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
|
|
@ -772,13 +775,15 @@ the pragma onwards within the same file.
|
|||
|
||||
.. code-block:: c
|
||||
|
||||
char a = 'xy'; // warning
|
||||
#if foo
|
||||
#endif foo // warning: extra tokens at end of #endif directive
|
||||
|
||||
#pragma clang system_header
|
||||
|
||||
char b = 'ab'; // no warning
|
||||
#if foo
|
||||
#endif foo // no warning
|
||||
|
||||
The :option:`--system-header-prefix=` and :option:`--no-system-header-prefix=`
|
||||
The `--system-header-prefix=` and `--no-system-header-prefix=`
|
||||
command-line arguments can be used to override whether subsets of an include
|
||||
path are treated as system headers. When the name in a ``#include`` directive
|
||||
is found within a header search path and starts with a system prefix, the
|
||||
|
|
@ -847,7 +852,7 @@ Generating a PCH File
|
|||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To generate a PCH file using Clang, one invokes Clang with the
|
||||
:option:`-x <language>-header` option. This mirrors the interface in GCC
|
||||
`-x <language>-header` option. This mirrors the interface in GCC
|
||||
for generating PCH files:
|
||||
|
||||
.. code-block:: console
|
||||
|
|
@ -910,7 +915,7 @@ location.
|
|||
Building a relocatable precompiled header requires two additional
|
||||
arguments. First, pass the ``--relocatable-pch`` flag to indicate that
|
||||
the resulting PCH file should be relocatable. Second, pass
|
||||
:option:`-isysroot /path/to/build`, which makes all includes for your library
|
||||
`-isysroot /path/to/build`, which makes all includes for your library
|
||||
relative to the build directory. For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
|
@ -920,9 +925,9 @@ relative to the build directory. For example:
|
|||
When loading the relocatable PCH file, the various headers used in the
|
||||
PCH file are found from the system header root. For example, ``mylib.h``
|
||||
can be found in ``/usr/include/mylib.h``. If the headers are installed
|
||||
in some other system root, the :option:`-isysroot` option can be used provide
|
||||
in some other system root, the `-isysroot` option can be used provide
|
||||
a different system root from which the headers will be based. For
|
||||
example, :option:`-isysroot /Developer/SDKs/MacOSX10.4u.sdk` will look for
|
||||
example, `-isysroot /Developer/SDKs/MacOSX10.4u.sdk` will look for
|
||||
``mylib.h`` in ``/Developer/SDKs/MacOSX10.4u.sdk/usr/include/mylib.h``.
|
||||
|
||||
Relocatable precompiled headers are intended to be used in a limited
|
||||
|
|
@ -986,6 +991,8 @@ are listed below.
|
|||
|
||||
**-f[no-]sanitize-recover=check1,check2,...**
|
||||
|
||||
**-f[no-]sanitize-recover=all**
|
||||
|
||||
Controls which checks enabled by ``-fsanitize=`` flag are non-fatal.
|
||||
If the check is fatal, program will halt after the first error
|
||||
of this kind is detected and error report is printed.
|
||||
|
|
@ -1038,6 +1045,11 @@ are listed below.
|
|||
Enable simple code coverage in addition to certain sanitizers.
|
||||
See :doc:`SanitizerCoverage` for more details.
|
||||
|
||||
**-f[no-]sanitize-stats**
|
||||
|
||||
Enable simple statistics gathering for the enabled sanitizers.
|
||||
See :doc:`SanitizerStats` for more details.
|
||||
|
||||
.. option:: -fsanitize-undefined-trap-on-error
|
||||
|
||||
Deprecated alias for ``-fsanitize-trap=undefined``.
|
||||
|
|
@ -1048,6 +1060,25 @@ are listed below.
|
|||
the behavior of sanitizers in the ``cfi`` group to allow checking
|
||||
of cross-DSO virtual and indirect calls.
|
||||
|
||||
.. option:: -ffast-math
|
||||
|
||||
Enable fast-math mode. This defines the ``__FAST_MATH__`` preprocessor
|
||||
macro, and lets the compiler make aggressive, potentially-lossy assumptions
|
||||
about floating-point math. These include:
|
||||
|
||||
* Floating-point math obeys regular algebraic rules for real numbers (e.g.
|
||||
``+`` and ``*`` are associative, ``x/y == x * (1/y)``, and
|
||||
``(a + b) * c == a * c + b * c``),
|
||||
* operands to floating-point operations are not equal to ``NaN`` and
|
||||
``Inf``, and
|
||||
* ``+0`` and ``-0`` are interchangeable.
|
||||
|
||||
.. option:: -fwhole-program-vtables
|
||||
|
||||
Enable whole-program vtable optimizations, such as single-implementation
|
||||
devirtualization and virtual constant propagation, for classes with
|
||||
:doc:`hidden LTO visibility <LTOVisibility>`. Requires ``-flto``.
|
||||
|
||||
.. option:: -fno-assume-sane-operator-new
|
||||
|
||||
Don't assume that the C++'s new operator is sane.
|
||||
|
|
@ -1114,6 +1145,16 @@ are listed below.
|
|||
This option restricts the generated code to use general registers
|
||||
only. This only applies to the AArch64 architecture.
|
||||
|
||||
.. option:: -mcompact-branches=[values]
|
||||
|
||||
Control the usage of compact branches for MIPSR6.
|
||||
|
||||
Valid values are: ``never``, ``optimal`` and ``always``.
|
||||
The default value is ``optimal`` which generates compact branches
|
||||
when a delay slot cannot be filled. ``never`` disables the usage of
|
||||
compact branches and ``always`` generates compact branches whenever
|
||||
possible.
|
||||
|
||||
**-f[no-]max-type-align=[number]**
|
||||
Instruct the code generator to not enforce a higher alignment than the given
|
||||
number (of bytes) when accessing memory via an opaque pointer or reference.
|
||||
|
|
@ -1461,19 +1502,21 @@ instrumentation:
|
|||
profile. As you make changes to your code, clang may no longer be able to
|
||||
use the profile data. It will warn you when this happens.
|
||||
|
||||
Profile generation and use can also be controlled by the GCC-compatible flags
|
||||
``-fprofile-generate`` and ``-fprofile-use``. Although these flags are
|
||||
semantically equivalent to their GCC counterparts, they *do not* handle
|
||||
GCC-compatible profiles. They are only meant to implement GCC's semantics
|
||||
with respect to profile creation and use.
|
||||
Profile generation using an alternative instrumentation method can be
|
||||
controlled by the GCC-compatible flags ``-fprofile-generate`` and
|
||||
``-fprofile-use``. Although these flags are semantically equivalent to
|
||||
their GCC counterparts, they *do not* handle GCC-compatible profiles.
|
||||
They are only meant to implement GCC's semantics with respect to
|
||||
profile creation and use.
|
||||
|
||||
.. option:: -fprofile-generate[=<dirname>]
|
||||
|
||||
Without any other arguments, ``-fprofile-generate`` behaves identically to
|
||||
``-fprofile-instr-generate``. When given a directory name, it generates the
|
||||
profile file ``default.profraw`` in the directory named ``dirname``. If
|
||||
``dirname`` does not exist, it will be created at runtime. The environment
|
||||
variable ``LLVM_PROFILE_FILE`` can be used to override the directory and
|
||||
The ``-fprofile-generate`` and ``-fprofile-generate=`` flags will use
|
||||
an alterantive instrumentation method for profile generation. When
|
||||
given a directory name, it generates the profile file
|
||||
``default.profraw`` in the directory named ``dirname``. If ``dirname``
|
||||
does not exist, it will be created at runtime. The environment variable
|
||||
``LLVM_PROFILE_FILE`` can be used to override the directory and
|
||||
filename for the profile file at runtime. For example,
|
||||
|
||||
.. code-block:: console
|
||||
|
|
@ -1689,10 +1732,6 @@ GCC extensions not implemented yet
|
|||
clang tries to be compatible with gcc as much as possible, but some gcc
|
||||
extensions are not implemented yet:
|
||||
|
||||
- clang does not support #pragma weak (`bug
|
||||
3679 <http://llvm.org/bugs/show_bug.cgi?id=3679>`_). Due to the uses
|
||||
described in the bug, this is likely to be implemented at some point,
|
||||
at least partially.
|
||||
- clang does not support decimal floating point types (``_Decimal32`` and
|
||||
friends) or fixed-point types (``_Fract`` and friends); nobody has
|
||||
expressed interest in these features yet, so it's hard to say when
|
||||
|
|
@ -1710,9 +1749,6 @@ extensions are not implemented yet:
|
|||
...
|
||||
local_function(1);
|
||||
|
||||
- clang does not support global register variables; this is unlikely to
|
||||
be implemented soon because it requires additional LLVM backend
|
||||
support.
|
||||
- clang does not support static initialization of flexible array
|
||||
members. This appears to be a rarely used extension, but could be
|
||||
implemented pending user demand.
|
||||
|
|
@ -1757,13 +1793,11 @@ Intentionally unsupported GCC extensions
|
|||
Microsoft extensions
|
||||
--------------------
|
||||
|
||||
clang has some experimental support for extensions from Microsoft Visual
|
||||
C++; to enable it, use the ``-fms-extensions`` command-line option. This is
|
||||
the default for Windows targets. Note that the support is incomplete.
|
||||
Some constructs such as ``dllexport`` on classes are ignored with a warning,
|
||||
and others such as `Microsoft IDL annotations
|
||||
<http://msdn.microsoft.com/en-us/library/8tesw2eh.aspx>`_ are silently
|
||||
ignored.
|
||||
clang has support for many extensions from Microsoft Visual C++. To enable these
|
||||
extensions, use the ``-fms-extensions`` command-line option. This is the default
|
||||
for Windows targets. Clang does not implement every pragma or declspec provided
|
||||
by MSVC, but the popular ones, such as ``__declspec(dllexport)`` and ``#pragma
|
||||
comment(lib)`` are well supported.
|
||||
|
||||
clang has a ``-fms-compatibility`` flag that makes clang accept enough
|
||||
invalid C++ to be able to parse most Microsoft headers. For example, it
|
||||
|
|
@ -1776,23 +1810,14 @@ for Windows targets.
|
|||
definitions until the end of a translation unit. This flag is enabled by
|
||||
default for Windows targets.
|
||||
|
||||
- clang allows setting ``_MSC_VER`` with ``-fmsc-version=``. It defaults to
|
||||
1700 which is the same as Visual C/C++ 2012. Any number is supported
|
||||
and can greatly affect what Windows SDK and c++stdlib headers clang
|
||||
can compile.
|
||||
- clang does not support the Microsoft extension where anonymous record
|
||||
members can be declared using user defined typedefs.
|
||||
- clang supports the Microsoft ``#pragma pack`` feature for controlling
|
||||
record layout. GCC also contains support for this feature, however
|
||||
where MSVC and GCC are incompatible clang follows the MSVC
|
||||
definition.
|
||||
- clang supports the Microsoft ``#pragma comment(lib, "foo.lib")`` feature for
|
||||
automatically linking against the specified library. Currently this feature
|
||||
only works with the Visual C++ linker.
|
||||
- clang supports the Microsoft ``#pragma comment(linker, "/flag:foo")`` feature
|
||||
for adding linker flags to COFF object files. The user is responsible for
|
||||
ensuring that the linker understands the flags.
|
||||
- clang defaults to C++11 for Windows targets.
|
||||
For compatibility with existing code that compiles with MSVC, clang defines the
|
||||
``_MSC_VER`` and ``_MSC_FULL_VER`` macros. These default to the values of 1800
|
||||
and 180000000 respectively, making clang look like an early release of Visual
|
||||
C++ 2013. The ``-fms-compatibility-version=`` flag overrides these values. It
|
||||
accepts a dotted version tuple, such as 19.00.23506. Changing the MSVC
|
||||
compatibility version makes clang behave more like that version of MSVC. For
|
||||
example, ``-fms-compatibility-version=19`` will enable C++14 features and define
|
||||
``char16_t`` and ``char32_t`` as builtin types.
|
||||
|
||||
.. _cxx:
|
||||
|
||||
|
|
@ -1849,8 +1874,8 @@ directives, ``depend`` clause for ``#pragma omp task`` directive (except for
|
|||
array sections), ``#pragma omp cancel`` and ``#pragma omp cancellation point``
|
||||
directives, and ``#pragma omp taskgroup`` directive.
|
||||
|
||||
Use :option:`-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with
|
||||
:option:`-fno-openmp`.
|
||||
Use `-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with
|
||||
`-fno-openmp`.
|
||||
|
||||
Controlling implementation limits
|
||||
---------------------------------
|
||||
|
|
@ -1859,7 +1884,7 @@ Controlling implementation limits
|
|||
|
||||
Controls code generation for OpenMP threadprivate variables. In presence of
|
||||
this option all threadprivate variables are generated the same way as thread
|
||||
local variables, using TLS support. If :option:`-fno-openmp-use-tls`
|
||||
local variables, using TLS support. If `-fno-openmp-use-tls`
|
||||
is provided or target does not support TLS, code generation for threadprivate
|
||||
variables relies on OpenMP runtime library.
|
||||
|
||||
|
|
@ -1883,7 +1908,7 @@ On ``x86_64-mingw32``, passing i128(by value) is incompatible with the
|
|||
Microsoft x64 calling convention. You might need to tweak
|
||||
``WinX86_64ABIInfo::classify()`` in lib/CodeGen/TargetInfo.cpp.
|
||||
|
||||
For the X86 target, clang supports the :option:`-m16` command line
|
||||
For the X86 target, clang supports the `-m16` command line
|
||||
argument which enables 16-bit code output. This is broadly similar to
|
||||
using ``asm(".code16gcc")`` with the GNU toolchain. The generated code
|
||||
and the ABI remains 32-bit but the assembler emits instructions
|
||||
|
|
@ -2019,8 +2044,9 @@ with a warning. For example:
|
|||
|
||||
To suppress warnings about unused arguments, use the ``-Qunused-arguments`` option.
|
||||
|
||||
Options that are not known to clang-cl will cause errors. If they are spelled with a
|
||||
leading ``/``, they will be mistaken for a filename:
|
||||
Options that are not known to clang-cl will be ignored by default. Use the
|
||||
``-Werror=unknown-argument`` option in order to treat them as errors. If these
|
||||
options are spelled with a leading ``/``, they will be mistaken for a filename:
|
||||
|
||||
::
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,41 @@ ExprInspection checks
|
|||
} while(0); // expected-warning{{SYMBOL DEAD}}
|
||||
|
||||
|
||||
- void clang_analyzer_explain(a single argument of any type);
|
||||
|
||||
This function explains the value of its argument in a human-readable manner
|
||||
in the warning message. You can make as many overrides of its prototype
|
||||
in the test code as necessary to explain various integral, pointer,
|
||||
or even record-type values.
|
||||
|
||||
Example usage::
|
||||
|
||||
void clang_analyzer_explain(int);
|
||||
void clang_analyzer_explain(void *);
|
||||
|
||||
void foo(int param, void *ptr) {
|
||||
clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
|
||||
if (!ptr)
|
||||
clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
|
||||
}
|
||||
|
||||
- size_t clang_analyzer_getExtent(void *);
|
||||
|
||||
This function returns the value that represents the extent of a memory region
|
||||
pointed to by the argument. This value is often difficult to obtain otherwise,
|
||||
because no valid code that produces this value. However, it may be useful
|
||||
for testing purposes, to see how well does the analyzer model region extents.
|
||||
|
||||
Example usage::
|
||||
|
||||
void foo() {
|
||||
int x, *y;
|
||||
size_t xs = clang_analyzer_getExtent(&x);
|
||||
clang_analyzer_explain(xs); // expected-warning{{'4'}}
|
||||
size_t ys = clang_analyzer_getExtent(&y);
|
||||
clang_analyzer_explain(ys); // expected-warning{{'8'}}
|
||||
}
|
||||
|
||||
Statistics
|
||||
==========
|
||||
|
||||
|
|
|
|||
|
|
@ -1,155 +0,0 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
default: html
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ClangStaticAnalyzer.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ClangStaticAnalyzer.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/ClangStaticAnalyzer"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ClangStaticAnalyzer"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
|
@ -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 @@ master_doc = 'index'
|
|||
|
||||
# General information about the project.
|
||||
project = u'Clang Static Analyzer'
|
||||
copyright = u'2013-2014, Analyzer Team'
|
||||
copyright = u'2013-%d, Analyzer Team' % date.today().year
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '3.4'
|
||||
version = '3.9'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.4'
|
||||
release = '3.9'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year
|
|||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '3.8'
|
||||
version = '3.9'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.8'
|
||||
release = '3.9'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
/// @mainpage clang
|
||||
/// \mainpage clang
|
||||
///
|
||||
/// @section main_intro Introduction
|
||||
/// \section main_intro Introduction
|
||||
/// Welcome to the clang project.
|
||||
///
|
||||
/// This documentation describes the @b internal software that makes
|
||||
/// up clang, not the @b external use of clang. There are no instructions
|
||||
/// here on how to use clang, only the APIs that make up the software. For
|
||||
/// usage instructions, please see the programmer's guide or reference
|
||||
/// This documentation describes the **internal** software that makes
|
||||
/// up clang, not the **external** use of clang. There are no instructions
|
||||
/// here on how to use clang, only the APIs that make up the software. For
|
||||
/// usage instructions, please see the programmer's guide or reference
|
||||
/// manual.
|
||||
///
|
||||
/// @section main_caveat Caveat
|
||||
/// This documentation is generated directly from the source code with doxygen.
|
||||
/// \section main_caveat Caveat
|
||||
/// This documentation is generated directly from the source code with doxygen.
|
||||
/// Since clang is constantly under active development, what you're about to
|
||||
/// read is out of date!
|
||||
|
|
@ -745,7 +745,7 @@ WARN_LOGFILE =
|
|||
|
||||
INPUT = @abs_srcdir@/../include \
|
||||
@abs_srcdir@/../lib \
|
||||
@abs_srcdir@/doxygen.intro
|
||||
@abs_srcdir@/doxygen-mainpage.dox
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
|
@ -1791,18 +1791,6 @@ GENERATE_XML = NO
|
|||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||
# listings (including syntax highlighting and cross-referencing information) to
|
||||
# the XML output. Note that enabling this will significantly increase the size
|
||||
|
|
@ -1949,7 +1937,7 @@ PREDEFINED =
|
|||
EXPAND_AS_DEFINED =
|
||||
|
||||
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
||||
# remove all refrences to function-like macros that are alone on a line, have an
|
||||
# remove all references to function-like macros that are alone on a line, have an
|
||||
# all uppercase name, and do not end with a semicolon. Such function macros are
|
||||
# typically used for boiler-plate code, and will confuse the parser if not
|
||||
# removed.
|
||||
|
|
|
|||
|
|
@ -28,9 +28,12 @@ Using Clang as a Compiler
|
|||
DataFlowSanitizer
|
||||
LeakSanitizer
|
||||
SanitizerCoverage
|
||||
SanitizerStats
|
||||
SanitizerSpecialCaseList
|
||||
ControlFlowIntegrity
|
||||
LTOVisibility
|
||||
SafeStack
|
||||
SourceBasedCodeCoverage
|
||||
Modules
|
||||
MSVCCompatibility
|
||||
CommandGuide/index
|
||||
|
|
@ -75,6 +78,7 @@ Design Documents
|
|||
DriverInternals
|
||||
PTHInternals
|
||||
PCHInternals
|
||||
ItaniumMangleAbiTags
|
||||
|
||||
|
||||
Indices and tables
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ def esc(text):
|
|||
except:
|
||||
doxygen_probes[url] = False
|
||||
if doxygen_probes[url]:
|
||||
return r'Matcher<<a href="%s">%s</a>>' % (url, name)
|
||||
return r'Matcher<<a href="%s">%s</a>>' % (url, name)
|
||||
else:
|
||||
return m.group(0)
|
||||
text = re.sub(
|
||||
|
|
@ -83,6 +83,11 @@ def strip_doxygen(comment):
|
|||
"""Returns the given comment without \-escaped words."""
|
||||
# If there is only a doxygen keyword in the line, delete the whole line.
|
||||
comment = re.sub(r'^\\[^\s]+\n', r'', comment, flags=re.M)
|
||||
|
||||
# If there is a doxygen \see command, change the \see prefix into "See also:".
|
||||
# FIXME: it would be better to turn this into a link to the target instead.
|
||||
comment = re.sub(r'\\see', r'See also:', comment)
|
||||
|
||||
# Delete the doxygen command and the following whitespace.
|
||||
comment = re.sub(r'\\[^\s]+\s+', r'', comment)
|
||||
return comment
|
||||
|
|
@ -90,7 +95,7 @@ def strip_doxygen(comment):
|
|||
def unify_arguments(args):
|
||||
"""Gets rid of anything the user doesn't care about in the argument list."""
|
||||
args = re.sub(r'internal::', r'', args)
|
||||
args = re.sub(r'const\s+', r'', args)
|
||||
args = re.sub(r'const\s+(.*)&', r'\1 ', args)
|
||||
args = re.sub(r'&', r' ', args)
|
||||
args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args)
|
||||
return args
|
||||
|
|
@ -226,7 +231,7 @@ def act_on_decl(declaration, comment, allowed_types):
|
|||
m = re.match(r"""^\s*AST_MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
|
||||
(?:\s*([^\s,]+)\s*,)?
|
||||
\s*([^\s,]+)\s*
|
||||
(?:,\s*([^\s,]+)\s*
|
||||
(?:,\s*([^,]+)\s*
|
||||
,\s*([^\s,]+)\s*)?
|
||||
(?:,\s*([^\s,]+)\s*
|
||||
,\s*([^\s,]+)\s*)?
|
||||
|
|
@ -259,6 +264,16 @@ def act_on_decl(declaration, comment, allowed_types):
|
|||
add_matcher('*', name, 'Matcher<*>', comment)
|
||||
return
|
||||
|
||||
# Parse Variadic functions.
|
||||
m = re.match(
|
||||
r"""^.*internal::VariadicFunction\s*<\s*([^,]+),\s*([^,]+),\s*[^>]+>\s*
|
||||
([a-zA-Z]*)\s*=\s*{.*};$""",
|
||||
declaration, flags=re.X)
|
||||
if m:
|
||||
result, arg, name = m.groups()[:3]
|
||||
add_matcher(result, name, '%s, ..., %s' % (arg, arg), comment)
|
||||
return
|
||||
|
||||
# Parse Variadic operator matchers.
|
||||
m = re.match(
|
||||
r"""^.*VariadicOperatorMatcherFunc\s*<\s*([^,]+),\s*([^\s>]+)\s*>\s*
|
||||
|
|
@ -358,11 +373,11 @@ traversal_matcher_table = sort_table('TRAVERSAL', traversal_matchers)
|
|||
|
||||
reference = open('../LibASTMatchersReference.html').read()
|
||||
reference = re.sub(r'<!-- START_DECL_MATCHERS.*END_DECL_MATCHERS -->',
|
||||
'%s', reference, flags=re.S) % node_matcher_table
|
||||
node_matcher_table, reference, flags=re.S)
|
||||
reference = re.sub(r'<!-- START_NARROWING_MATCHERS.*END_NARROWING_MATCHERS -->',
|
||||
'%s', reference, flags=re.S) % narrowing_matcher_table
|
||||
narrowing_matcher_table, reference, flags=re.S)
|
||||
reference = re.sub(r'<!-- START_TRAVERSAL_MATCHERS.*END_TRAVERSAL_MATCHERS -->',
|
||||
'%s', reference, flags=re.S) % traversal_matcher_table
|
||||
traversal_matcher_table, reference, flags=re.S)
|
||||
|
||||
with open('../LibASTMatchersReference.html', 'wb') as output:
|
||||
output.write(reference)
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@
|
|||
# Run from the directory in which this file is located to update the docs.
|
||||
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
import urllib2
|
||||
|
||||
FORMAT_STYLE_FILE = '../../include/clang/Format/Format.h'
|
||||
DOC_FILE = '../ClangFormatStyleOptions.rst'
|
||||
CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..')
|
||||
FORMAT_STYLE_FILE = os.path.join(CLANG_DIR, 'include/clang/Format/Format.h')
|
||||
DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormatStyleOptions.rst')
|
||||
|
||||
|
||||
def substitute(text, tag, contents):
|
||||
|
|
@ -77,7 +79,7 @@ class Enum:
|
|||
class EnumValue:
|
||||
def __init__(self, name, comment):
|
||||
self.name = name
|
||||
self.comment = comment.strip()
|
||||
self.comment = comment
|
||||
|
||||
def __str__(self):
|
||||
return '* ``%s`` (in configuration: ``%s``)\n%s' % (
|
||||
|
|
@ -86,8 +88,12 @@ class EnumValue:
|
|||
doxygen2rst(indent(self.comment, 2)))
|
||||
|
||||
def clean_comment_line(line):
|
||||
if line == '/// \\code':
|
||||
return '\n.. code-block:: c++\n\n'
|
||||
match = re.match(r'^/// \\code(\{.(\w+)\})?$', line)
|
||||
if match:
|
||||
lang = match.groups()[1]
|
||||
if not lang:
|
||||
lang = 'c++'
|
||||
return '\n.. code-block:: %s\n\n' % lang
|
||||
if line == '/// \\endcode':
|
||||
return ''
|
||||
return line[4:] + '\n'
|
||||
|
|
|
|||
88
examples/AnnotateFunctions/AnnotateFunctions.cpp
Normal file
88
examples/AnnotateFunctions/AnnotateFunctions.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
//===- AnnotateFunctions.cpp ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Example clang plugin which adds an annotation to every function in
|
||||
// translation units that start with #pragma enable_annotate.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Frontend/FrontendPluginRegistry.h"
|
||||
#include "clang/AST/AST.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Lex/LexDiagnostic.h"
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
|
||||
static bool EnableAnnotate = false;
|
||||
static bool HandledDecl = false;
|
||||
|
||||
class AnnotateFunctionsConsumer : public ASTConsumer {
|
||||
public:
|
||||
bool HandleTopLevelDecl(DeclGroupRef DG) override {
|
||||
HandledDecl = true;
|
||||
if (!EnableAnnotate)
|
||||
return true;
|
||||
for (auto D : DG)
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
|
||||
FD->addAttr(AnnotateAttr::CreateImplicit(FD->getASTContext(),
|
||||
"example_annotation"));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class AnnotateFunctionsAction : public PluginASTAction {
|
||||
public:
|
||||
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
|
||||
llvm::StringRef) override {
|
||||
return llvm::make_unique<AnnotateFunctionsConsumer>();
|
||||
}
|
||||
|
||||
bool ParseArgs(const CompilerInstance &CI,
|
||||
const std::vector<std::string> &args) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
PluginASTAction::ActionType getActionType() override {
|
||||
return AddBeforeMainAction;
|
||||
}
|
||||
};
|
||||
|
||||
class PragmaAnnotateHandler : public PragmaHandler {
|
||||
public:
|
||||
PragmaAnnotateHandler() : PragmaHandler("enable_annotate") { }
|
||||
|
||||
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &PragmaTok) override {
|
||||
|
||||
Token Tok;
|
||||
PP.LexUnexpandedToken(Tok);
|
||||
if (Tok.isNot(tok::eod))
|
||||
PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
|
||||
|
||||
if (HandledDecl) {
|
||||
DiagnosticsEngine &D = PP.getDiagnostics();
|
||||
unsigned ID = D.getCustomDiagID(
|
||||
DiagnosticsEngine::Error,
|
||||
"#pragma enable_annotate not allowed after declarations");
|
||||
D.Report(PragmaTok.getLocation(), ID);
|
||||
}
|
||||
|
||||
EnableAnnotate = true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static FrontendPluginRegistry::Add<AnnotateFunctionsAction>
|
||||
X("annotate-fns", "annotate functions");
|
||||
|
||||
static PragmaHandlerRegistry::Add<PragmaAnnotateHandler>
|
||||
Y("enable_annotate","enable annotation");
|
||||
11
examples/AnnotateFunctions/CMakeLists.txt
Normal file
11
examples/AnnotateFunctions/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp)
|
||||
|
||||
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
|
||||
target_link_libraries(AnnotateFunctions PRIVATE
|
||||
clangAST
|
||||
clangBasic
|
||||
clangFrontend
|
||||
clangLex
|
||||
LLVMSupport
|
||||
)
|
||||
endif()
|
||||
|
|
@ -8,3 +8,4 @@ add_subdirectory(analyzer-plugin)
|
|||
endif()
|
||||
add_subdirectory(clang-interpreter)
|
||||
add_subdirectory(PrintFunctionNames)
|
||||
add_subdirectory(AnnotateFunctions)
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
##===- examples/Makefile -----------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL := ..
|
||||
|
||||
PARALLEL_DIRS := analyzer-plugin clang-interpreter PrintFunctionNames
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
|
@ -12,7 +12,7 @@ endif()
|
|||
add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp)
|
||||
|
||||
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
|
||||
target_link_libraries(PrintFunctionNames ${cmake_2_8_12_PRIVATE}
|
||||
target_link_libraries(PrintFunctionNames PRIVATE
|
||||
clangAST
|
||||
clangBasic
|
||||
clangFrontend
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
##===- examples/PrintFunctionNames/Makefile ----------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL := ../..
|
||||
LIBRARYNAME = PrintFunctionNames
|
||||
|
||||
# If we don't need RTTI or EH, there's no reason to export anything
|
||||
# from the plugin.
|
||||
ifneq ($(REQUIRES_RTTI), 1)
|
||||
ifneq ($(REQUIRES_EH), 1)
|
||||
EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/PrintFunctionNames.exports
|
||||
endif
|
||||
endif
|
||||
|
||||
LINK_LIBS_IN_SHARED = 0
|
||||
LOADABLE_MODULE = 1
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
LDFLAGS=-Wl,-undefined,dynamic_lookup
|
||||
endif
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
add_llvm_loadable_module(SampleAnalyzerPlugin MainCallChecker.cpp)
|
||||
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/SampleAnalyzerPlugin.exports)
|
||||
add_llvm_loadable_module(SampleAnalyzerPlugin MainCallChecker.cpp PLUGIN_TOOL clang)
|
||||
|
||||
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
|
||||
target_link_libraries(SampleAnalyzerPlugin ${cmake_2_8_12_PRIVATE}
|
||||
target_link_libraries(SampleAnalyzerPlugin PRIVATE
|
||||
clangAnalysis
|
||||
clangAST
|
||||
clangStaticAnalyzerCore
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
##===- examples/analyzer-plugin/Makefile -------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL := ../..
|
||||
LIBRARYNAME = SampleAnalyzerPlugin
|
||||
|
||||
LINK_LIBS_IN_SHARED = 0
|
||||
LOADABLE_MODULE = 1
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
LDFLAGS=-Wl,-undefined,dynamic_lookup
|
||||
endif
|
||||
2
examples/analyzer-plugin/SampleAnalyzerPlugin.exports
Normal file
2
examples/analyzer-plugin/SampleAnalyzerPlugin.exports
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
clang_registerCheckers
|
||||
clang_analyzerAPIVersionString
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
##===- examples/clang-interpreter/Makefile -----------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL := ../..
|
||||
|
||||
TOOLNAME = clang-interpreter
|
||||
NO_INSTALL = 1
|
||||
|
||||
# No plugins, optimize startup time.
|
||||
TOOL_NO_EXPORTS = 1
|
||||
|
||||
LINK_COMPONENTS := mcjit interpreter nativecodegen bitreader bitwriter irreader \
|
||||
ipo linker selectiondag asmparser instrumentation objcarcopts option
|
||||
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a clangCodeGen.a \
|
||||
clangParse.a clangSema.a clangStaticAnalyzerFrontend.a \
|
||||
clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
|
||||
clangAnalysis.a clangRewrite.a clangRewriteFrontend.a \
|
||||
clangEdit.a clangAST.a clangLex.a clangBasic.a LLVMCore.a \
|
||||
LLVMExecutionEngine.a LLVMMC.a LLVMMCJIT.a LLVMRuntimeDyld.a \
|
||||
LLVMObject.a LLVMSupport.a LLVMProfileData.a
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
CLANG_LEVEL := ..
|
||||
DIRS := clang clang-c
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
|
||||
*/
|
||||
#define CINDEX_VERSION_MAJOR 0
|
||||
#define CINDEX_VERSION_MINOR 32
|
||||
#define CINDEX_VERSION_MINOR 35
|
||||
|
||||
#define CINDEX_VERSION_ENCODE(major, minor) ( \
|
||||
((major) * 10000) \
|
||||
|
|
@ -326,7 +326,7 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
|
|||
*
|
||||
* \param tu the translation unit
|
||||
*
|
||||
* \param file_name the name of the file.
|
||||
* \param file_name the name of the file.
|
||||
*
|
||||
* \returns the file handle for the named file in the translation unit \p tu,
|
||||
* or a NULL file handle if the file was not a part of this translation unit.
|
||||
|
|
@ -1208,7 +1208,18 @@ enum CXTranslationUnit_Flags {
|
|||
* trades runtime on the first parse (serializing the preamble takes time) for
|
||||
* reduced runtime on the second parse (can now reuse the preamble).
|
||||
*/
|
||||
CXTranslationUnit_CreatePreambleOnFirstParse = 0x100
|
||||
CXTranslationUnit_CreatePreambleOnFirstParse = 0x100,
|
||||
|
||||
/**
|
||||
* \brief Do not stop processing when fatal errors are encountered.
|
||||
*
|
||||
* When fatal errors are encountered while parsing a translation unit,
|
||||
* semantic analysis is typically stopped early when compiling code. A common
|
||||
* source for fatal errors are unresolvable include files. For the
|
||||
* purposes of an IDE, this is undesirable behavior and as much information
|
||||
* as possible should be reported. Use this flag to enable this behavior.
|
||||
*/
|
||||
CXTranslationUnit_KeepGoing = 0x200
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1921,7 +1932,7 @@ enum CXCursorKind {
|
|||
*/
|
||||
CXCursor_CXXDeleteExpr = 135,
|
||||
|
||||
/** \brief A unary expression.
|
||||
/** \brief A unary expression. (noexcept, sizeof, or other traits)
|
||||
*/
|
||||
CXCursor_UnaryExpr = 136,
|
||||
|
||||
|
|
@ -2003,7 +2014,11 @@ enum CXCursorKind {
|
|||
*/
|
||||
CXCursor_OMPArraySectionExpr = 147,
|
||||
|
||||
CXCursor_LastExpr = CXCursor_OMPArraySectionExpr,
|
||||
/** \brief Represents an @available(...) check.
|
||||
*/
|
||||
CXCursor_ObjCAvailabilityCheckExpr = 148,
|
||||
|
||||
CXCursor_LastExpr = CXCursor_ObjCAvailabilityCheckExpr,
|
||||
|
||||
/* Statements */
|
||||
CXCursor_FirstStmt = 200,
|
||||
|
|
@ -2270,11 +2285,47 @@ enum CXCursorKind {
|
|||
*/
|
||||
CXCursor_OMPTaskLoopSimdDirective = 259,
|
||||
|
||||
/** \brief OpenMP distribute directive.
|
||||
/** \brief OpenMP distribute directive.
|
||||
*/
|
||||
CXCursor_OMPDistributeDirective = 260,
|
||||
|
||||
CXCursor_LastStmt = CXCursor_OMPDistributeDirective,
|
||||
/** \brief OpenMP target enter data directive.
|
||||
*/
|
||||
CXCursor_OMPTargetEnterDataDirective = 261,
|
||||
|
||||
/** \brief OpenMP target exit data directive.
|
||||
*/
|
||||
CXCursor_OMPTargetExitDataDirective = 262,
|
||||
|
||||
/** \brief OpenMP target parallel directive.
|
||||
*/
|
||||
CXCursor_OMPTargetParallelDirective = 263,
|
||||
|
||||
/** \brief OpenMP target parallel for directive.
|
||||
*/
|
||||
CXCursor_OMPTargetParallelForDirective = 264,
|
||||
|
||||
/** \brief OpenMP target update directive.
|
||||
*/
|
||||
CXCursor_OMPTargetUpdateDirective = 265,
|
||||
|
||||
/** \brief OpenMP distribute parallel for directive.
|
||||
*/
|
||||
CXCursor_OMPDistributeParallelForDirective = 266,
|
||||
|
||||
/** \brief OpenMP distribute parallel for simd directive.
|
||||
*/
|
||||
CXCursor_OMPDistributeParallelForSimdDirective = 267,
|
||||
|
||||
/** \brief OpenMP distribute simd directive.
|
||||
*/
|
||||
CXCursor_OMPDistributeSimdDirective = 268,
|
||||
|
||||
/** \brief OpenMP target parallel for simd directive.
|
||||
*/
|
||||
CXCursor_OMPTargetParallelForSimdDirective = 269,
|
||||
|
||||
CXCursor_LastStmt = CXCursor_OMPTargetParallelForSimdDirective,
|
||||
|
||||
/**
|
||||
* \brief Cursor that represents the translation unit itself.
|
||||
|
|
@ -2328,8 +2379,12 @@ enum CXCursorKind {
|
|||
*/
|
||||
CXCursor_ModuleImportDecl = 600,
|
||||
CXCursor_TypeAliasTemplateDecl = 601,
|
||||
/**
|
||||
* \brief A static_assert or _Static_assert node
|
||||
*/
|
||||
CXCursor_StaticAssert = 602,
|
||||
CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl,
|
||||
CXCursor_LastExtraDecl = CXCursor_TypeAliasTemplateDecl,
|
||||
CXCursor_LastExtraDecl = CXCursor_StaticAssert,
|
||||
|
||||
/**
|
||||
* \brief A code completion overload candidate.
|
||||
|
|
@ -2430,6 +2485,11 @@ CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind);
|
|||
*/
|
||||
CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind);
|
||||
|
||||
/**
|
||||
* \brief Determine whether the given cursor has any attributes.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Cursor_hasAttrs(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine whether the given cursor kind represents an invalid
|
||||
* cursor.
|
||||
|
|
@ -2526,7 +2586,7 @@ typedef struct CXPlatformAvailability {
|
|||
* \brief A string that describes the platform for which this structure
|
||||
* provides availability information.
|
||||
*
|
||||
* Possible values are "ios" or "macosx".
|
||||
* Possible values are "ios" or "macos".
|
||||
*/
|
||||
CXString Platform;
|
||||
/**
|
||||
|
|
@ -2897,6 +2957,7 @@ enum CXTypeKind {
|
|||
CXType_ObjCId = 27,
|
||||
CXType_ObjCClass = 28,
|
||||
CXType_ObjCSel = 29,
|
||||
CXType_Float128 = 30,
|
||||
CXType_FirstBuiltin = CXType_Void,
|
||||
CXType_LastBuiltin = CXType_ObjCSel,
|
||||
|
||||
|
|
@ -2918,7 +2979,14 @@ enum CXTypeKind {
|
|||
CXType_VariableArray = 115,
|
||||
CXType_DependentSizedArray = 116,
|
||||
CXType_MemberPointer = 117,
|
||||
CXType_Auto = 118
|
||||
CXType_Auto = 118,
|
||||
|
||||
/**
|
||||
* \brief Represents a type that was referred to using an elaborated type keyword.
|
||||
*
|
||||
* E.g., struct S, or via a qualified name, e.g., N::M::type, or both.
|
||||
*/
|
||||
CXType_Elaborated = 119
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2938,6 +3006,9 @@ enum CXCallingConv {
|
|||
CXCallingConv_X86_64Win64 = 10,
|
||||
CXCallingConv_X86_64SysV = 11,
|
||||
CXCallingConv_X86VectorCall = 12,
|
||||
CXCallingConv_Swift = 13,
|
||||
CXCallingConv_PreserveMost = 14,
|
||||
CXCallingConv_PreserveAll = 15,
|
||||
|
||||
CXCallingConv_Invalid = 100,
|
||||
CXCallingConv_Unexposed = 200
|
||||
|
|
@ -3169,6 +3240,24 @@ CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE unsigned clang_isConstQualifiedType(CXType T);
|
||||
|
||||
/**
|
||||
* \brief Determine whether a CXCursor that is a macro, is
|
||||
* function like.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Cursor_isMacroFunctionLike(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine whether a CXCursor that is a macro, is a
|
||||
* builtin one.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Cursor_isMacroBuiltin(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine whether a CXCursor that is a function declaration, is an
|
||||
* inline declaration.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Cursor_isFunctionInlined(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine whether a CXType has the "volatile" qualifier set,
|
||||
* without looking through typedefs that may have added "volatile" at
|
||||
|
|
@ -3198,6 +3287,11 @@ CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C);
|
||||
|
||||
/**
|
||||
* Returns the Objective-C type encoding for the specified CXType.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_Type_getObjCEncoding(CXType type);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the spelling of a given CXTypeKind.
|
||||
*/
|
||||
|
|
@ -3281,6 +3375,13 @@ CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE long long clang_getArraySize(CXType T);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the type named by the qualified-id.
|
||||
*
|
||||
* If a non-elaborated type is passed in, an invalid type is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
|
||||
|
||||
/**
|
||||
* \brief List the possible error codes for \c clang_Type_getSizeOf,
|
||||
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
|
||||
|
|
@ -3612,8 +3713,8 @@ typedef enum CXChildVisitResult
|
|||
* Visits the children of a cursor using the specified block. Behaves
|
||||
* identically to clang_visitChildren() in all other respects.
|
||||
*/
|
||||
unsigned clang_visitChildrenWithBlock(CXCursor parent,
|
||||
CXCursorVisitorBlock block);
|
||||
CINDEX_LINKAGE unsigned clang_visitChildrenWithBlock(CXCursor parent,
|
||||
CXCursorVisitorBlock block);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
@ -3834,7 +3935,8 @@ typedef enum {
|
|||
CXObjCPropertyAttr_atomic = 0x100,
|
||||
CXObjCPropertyAttr_weak = 0x200,
|
||||
CXObjCPropertyAttr_strong = 0x400,
|
||||
CXObjCPropertyAttr_unsafe_unretained = 0x800
|
||||
CXObjCPropertyAttr_unsafe_unretained = 0x800,
|
||||
CXObjCPropertyAttr_class = 0x1000
|
||||
} CXObjCPropertyAttrKind;
|
||||
|
||||
/**
|
||||
|
|
@ -4015,11 +4117,36 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit,
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ constructor is a converting constructor.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ constructor is a copy constructor.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ constructor is the default constructor.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ constructor is a move constructor.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ field is declared 'mutable'.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ method is declared '= default'.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ member function or member function template is
|
||||
* pure virtual.
|
||||
|
|
@ -4900,7 +5027,7 @@ CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void);
|
|||
* Note that the column should point just after the syntactic construct that
|
||||
* initiated code completion, and not in the middle of a lexical token.
|
||||
*
|
||||
* \param unsaved_files the Tiles that have not yet been saved to disk
|
||||
* \param unsaved_files the Files that have not yet been saved to disk
|
||||
* but may be required for parsing or code completion, including the
|
||||
* contents of those files. The contents and name of these files (as
|
||||
* specified by CXUnsavedFile) are copied when necessary, so the
|
||||
|
|
@ -5077,6 +5204,59 @@ CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
|
|||
CXInclusionVisitor visitor,
|
||||
CXClientData client_data);
|
||||
|
||||
typedef enum {
|
||||
CXEval_Int = 1 ,
|
||||
CXEval_Float = 2,
|
||||
CXEval_ObjCStrLiteral = 3,
|
||||
CXEval_StrLiteral = 4,
|
||||
CXEval_CFStr = 5,
|
||||
CXEval_Other = 6,
|
||||
|
||||
CXEval_UnExposed = 0
|
||||
|
||||
} CXEvalResultKind ;
|
||||
|
||||
/**
|
||||
* \brief Evaluation result of a cursor
|
||||
*/
|
||||
typedef void * CXEvalResult;
|
||||
|
||||
/**
|
||||
* \brief If cursor is a statement declaration tries to evaluate the
|
||||
* statement and if its variable, tries to evaluate its initializer,
|
||||
* into its corresponding type.
|
||||
*/
|
||||
CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Returns the kind of the evaluated result.
|
||||
*/
|
||||
CINDEX_LINKAGE CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Returns the evaluation result as integer if the
|
||||
* kind is Int.
|
||||
*/
|
||||
CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Returns the evaluation result as double if the
|
||||
* kind is double.
|
||||
*/
|
||||
CINDEX_LINKAGE double clang_EvalResult_getAsDouble(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Returns the evaluation result as a constant string if the
|
||||
* kind is other than Int or float. User must not free this pointer,
|
||||
* instead call clang_EvalResult_dispose on the CXEvalResult returned
|
||||
* by clang_Cursor_Evaluate.
|
||||
*/
|
||||
CINDEX_LINKAGE const char* clang_EvalResult_getAsStr(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Disposes the created Eval memory.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_EvalResult_dispose(CXEvalResult E);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
@ -5150,7 +5330,7 @@ enum CXVisitorResult {
|
|||
CXVisit_Continue
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct CXCursorAndRangeVisitor {
|
||||
void *context;
|
||||
enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange);
|
||||
} CXCursorAndRangeVisitor;
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
CLANG_LEVEL := ../..
|
||||
DIRS :=
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
IntIncludeDir = $(DESTDIR)$(PROJ_internal_prefix)/include
|
||||
|
||||
install-local::
|
||||
$(Echo) Installing Clang C API include files
|
||||
$(Verb) $(MKDIR) $(IntIncludeDir)
|
||||
$(Verb) if test -d "$(PROJ_SRC_DIR)" ; then \
|
||||
cd $(PROJ_SRC_DIR)/.. && \
|
||||
for hdr in `find clang-c -type f '!' '(' -name '*~' \
|
||||
-o -name '.#*' -o -name '*.in' -o -name '*.txt' \
|
||||
-o -name 'Makefile' -o -name '*.td' ')' -print \
|
||||
| grep -v CVS | grep -v .svn | grep -v .dir` ; do \
|
||||
instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \
|
||||
if test \! -d "$$instdir" ; then \
|
||||
$(EchoCmd) Making install directory $$instdir ; \
|
||||
$(MKDIR) $$instdir ;\
|
||||
fi ; \
|
||||
$(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \
|
||||
done ; \
|
||||
fi
|
||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
$(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang-c" ; then \
|
||||
cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
|
||||
for hdr in `find clang-c -type f '!' '(' -name 'Makefile' ')' -print \
|
||||
| grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
|
||||
instdir=`dirname "$(IntIncludeDir)/$$hdr"` ; \
|
||||
if test \! -d "$$instdir" ; then \
|
||||
$(EchoCmd) Making install directory $$instdir ; \
|
||||
$(MKDIR) $$instdir ;\
|
||||
fi ; \
|
||||
$(DataInstall) $$hdr $(IntIncludeDir)/$$hdr ; \
|
||||
done ; \
|
||||
fi
|
||||
endif
|
||||
|
|
@ -22,7 +22,7 @@ protected:
|
|||
bool BeginInvocation(CompilerInstance &CI) override;
|
||||
|
||||
public:
|
||||
CheckAction(FrontendAction *WrappedAction);
|
||||
CheckAction(std::unique_ptr<FrontendAction> WrappedAction);
|
||||
};
|
||||
|
||||
class ModifyAction : public WrapperFrontendAction {
|
||||
|
|
@ -30,7 +30,7 @@ protected:
|
|||
bool BeginInvocation(CompilerInstance &CI) override;
|
||||
|
||||
public:
|
||||
ModifyAction(FrontendAction *WrappedAction);
|
||||
ModifyAction(std::unique_ptr<FrontendAction> WrappedAction);
|
||||
};
|
||||
|
||||
class MigrateSourceAction : public ASTFrontendAction {
|
||||
|
|
@ -49,7 +49,8 @@ protected:
|
|||
bool BeginInvocation(CompilerInstance &CI) override;
|
||||
|
||||
public:
|
||||
MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
|
||||
MigrateAction(std::unique_ptr<FrontendAction> WrappedAction,
|
||||
StringRef migrateDir,
|
||||
StringRef plistOut,
|
||||
bool emitPremigrationARCErrors);
|
||||
};
|
||||
|
|
@ -61,8 +62,8 @@ class ObjCMigrateAction : public WrapperFrontendAction {
|
|||
FileRemapper Remapper;
|
||||
CompilerInstance *CompInst;
|
||||
public:
|
||||
ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
|
||||
unsigned migrateAction);
|
||||
ObjCMigrateAction(std::unique_ptr<FrontendAction> WrappedAction,
|
||||
StringRef migrateDir, unsigned migrateAction);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ public:
|
|||
/// \returns true to continue parsing, or false to abort parsing.
|
||||
virtual bool HandleTopLevelDecl(DeclGroupRef D);
|
||||
|
||||
/// \brief This callback is invoked each time an inline method definition is
|
||||
/// completed.
|
||||
virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
|
||||
/// \brief This callback is invoked each time an inline (method or friend)
|
||||
/// function definition in a class is completed.
|
||||
virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
|
||||
|
||||
/// HandleInterestingDecl - Handle the specified interesting declaration. This
|
||||
/// is called by the AST reader when deserializing things that might interest
|
||||
|
|
@ -94,21 +94,6 @@ public:
|
|||
/// The default implementation passes it to HandleTopLevelDecl.
|
||||
virtual void HandleImplicitImportDecl(ImportDecl *D);
|
||||
|
||||
/// \brief Handle a pragma that appends to Linker Options. Currently this
|
||||
/// only exists to support Microsoft's #pragma comment(linker, "/foo").
|
||||
virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}
|
||||
|
||||
/// \brief Handle a pragma that emits a mismatch identifier and value to the
|
||||
/// object file for the linker to work with. Currently, this only exists to
|
||||
/// support Microsoft's #pragma detect_mismatch.
|
||||
virtual void HandleDetectMismatch(llvm::StringRef Name,
|
||||
llvm::StringRef Value) {}
|
||||
|
||||
/// \brief Handle a dependent library created by a pragma in the source.
|
||||
/// Currently this only exists to support Microsoft's
|
||||
/// #pragma comment(lib, "/foo").
|
||||
virtual void HandleDependentLibrary(llvm::StringRef Lib) {}
|
||||
|
||||
/// CompleteTentativeDefinition - Callback invoked at the end of a translation
|
||||
/// unit to notify the consumer that the given tentative definition should be
|
||||
/// completed.
|
||||
|
|
@ -120,6 +105,10 @@ public:
|
|||
/// modified by the introduction of an implicit zero initializer.
|
||||
virtual void CompleteTentativeDefinition(VarDecl *D) {}
|
||||
|
||||
/// \brief Callback invoked when an MSInheritanceAttr has been attached to a
|
||||
/// CXXRecordDecl.
|
||||
virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
|
||||
|
||||
/// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
|
||||
// variable has been instantiated.
|
||||
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/TinyPtrVector.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
|
|
@ -128,6 +129,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
|
||||
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
|
||||
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
|
||||
mutable llvm::FoldingSet<DependentUnaryTransformType>
|
||||
DependentUnaryTransformTypes;
|
||||
mutable llvm::FoldingSet<AutoType> AutoTypes;
|
||||
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
|
||||
llvm::FoldingSet<AttributedType> AttributedTypes;
|
||||
|
|
@ -212,9 +215,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
/// \brief The typedef for the __uint128_t type.
|
||||
mutable TypedefDecl *UInt128Decl;
|
||||
|
||||
/// \brief The typedef for the __float128 stub type.
|
||||
mutable TypeDecl *Float128StubDecl;
|
||||
|
||||
/// \brief The typedef for the target specific predefined
|
||||
/// __builtin_va_list type.
|
||||
mutable TypedefDecl *BuiltinVaListDecl;
|
||||
|
|
@ -243,6 +243,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
QualType ObjCClassRedefinitionType;
|
||||
QualType ObjCSelRedefinitionType;
|
||||
|
||||
/// The identifier 'bool'.
|
||||
mutable IdentifierInfo *BoolName = nullptr;
|
||||
|
||||
/// The identifier 'NSObject'.
|
||||
IdentifierInfo *NSObjectName = nullptr;
|
||||
|
||||
|
|
@ -252,9 +255,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
/// The identifier '__make_integer_seq'.
|
||||
mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
|
||||
|
||||
/// The identifier '__type_pack_element'.
|
||||
mutable IdentifierInfo *TypePackElementName = nullptr;
|
||||
|
||||
QualType ObjCConstantStringType;
|
||||
mutable RecordDecl *CFConstantStringTypeDecl;
|
||||
|
||||
mutable RecordDecl *CFConstantStringTagDecl;
|
||||
mutable TypedefDecl *CFConstantStringTypeDecl;
|
||||
|
||||
mutable QualType ObjCSuperType;
|
||||
|
||||
QualType ObjCNSStringType;
|
||||
|
|
@ -392,8 +399,8 @@ private:
|
|||
|
||||
/// \brief Side-table of mangling numbers for declarations which rarely
|
||||
/// need them (like static local vars).
|
||||
llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
|
||||
llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
|
||||
llvm::MapVector<const NamedDecl *, unsigned> MangleNumbers;
|
||||
llvm::MapVector<const VarDecl *, unsigned> StaticLocalNumbers;
|
||||
|
||||
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
|
||||
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
|
||||
|
|
@ -406,6 +413,7 @@ private:
|
|||
TranslationUnitDecl *TUDecl;
|
||||
mutable ExternCContextDecl *ExternCContext;
|
||||
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
|
||||
mutable BuiltinTemplateDecl *TypePackElementDecl;
|
||||
|
||||
/// \brief The associated SourceManager object.a
|
||||
SourceManager &SourceMgr;
|
||||
|
|
@ -817,6 +825,9 @@ public:
|
|||
overridden_methods_end(const CXXMethodDecl *Method) const;
|
||||
|
||||
unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
|
||||
typedef llvm::iterator_range<overridden_cxx_method_iterator>
|
||||
overridden_method_range;
|
||||
overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;
|
||||
|
||||
/// \brief Note that the given C++ \p Method overrides the given \p
|
||||
/// Overridden method.
|
||||
|
|
@ -876,6 +887,7 @@ public:
|
|||
|
||||
ExternCContextDecl *getExternCContextDecl() const;
|
||||
BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
|
||||
BuiltinTemplateDecl *getTypePackElementDecl() const;
|
||||
|
||||
// Builtin Types.
|
||||
CanQualType VoidTy;
|
||||
|
|
@ -889,20 +901,19 @@ public:
|
|||
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
|
||||
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
|
||||
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
|
||||
CanQualType FloatTy, DoubleTy, LongDoubleTy;
|
||||
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
|
||||
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
|
||||
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
|
||||
CanQualType Float128ComplexTy;
|
||||
CanQualType VoidPtrTy, NullPtrTy;
|
||||
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
|
||||
CanQualType BuiltinFnTy;
|
||||
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
|
||||
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
|
||||
CanQualType ObjCBuiltinBoolTy;
|
||||
CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
|
||||
CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy;
|
||||
CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy;
|
||||
CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy;
|
||||
CanQualType OCLImage3dTy;
|
||||
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
||||
CanQualType SingletonId;
|
||||
#include "clang/Basic/OpenCLImageTypes.def"
|
||||
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
|
||||
CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
|
||||
CanQualType OMPArraySectionTy;
|
||||
|
|
@ -966,9 +977,6 @@ public:
|
|||
/// \brief Retrieve the declaration for the 128-bit unsigned integer type.
|
||||
TypedefDecl *getUInt128Decl() const;
|
||||
|
||||
/// \brief Retrieve the declaration for a 128-bit float stub type.
|
||||
TypeDecl *getFloat128StubType() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Constructors
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
@ -1229,13 +1237,12 @@ public:
|
|||
TemplateTypeParmDecl *ParmDecl = nullptr) const;
|
||||
|
||||
QualType getTemplateSpecializationType(TemplateName T,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
QualType Canon = QualType()) const;
|
||||
|
||||
QualType getCanonicalTemplateSpecializationType(TemplateName T,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs) const;
|
||||
QualType
|
||||
getCanonicalTemplateSpecializationType(TemplateName T,
|
||||
ArrayRef<TemplateArgument> Args) const;
|
||||
|
||||
QualType getTemplateSpecializationType(TemplateName T,
|
||||
const TemplateArgumentListInfo &Args,
|
||||
|
|
@ -1260,11 +1267,9 @@ public:
|
|||
NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Name,
|
||||
const TemplateArgumentListInfo &Args) const;
|
||||
QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
|
||||
NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Name,
|
||||
unsigned NumArgs,
|
||||
const TemplateArgument *Args) const;
|
||||
QualType getDependentTemplateSpecializationType(
|
||||
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
|
||||
|
||||
QualType getPackExpansionType(QualType Pattern,
|
||||
Optional<unsigned> NumExpansions);
|
||||
|
|
@ -1381,10 +1386,12 @@ public:
|
|||
/// if it hasn't yet been built.
|
||||
QualType getRawCFConstantStringType() const {
|
||||
if (CFConstantStringTypeDecl)
|
||||
return getTagDeclType(CFConstantStringTypeDecl);
|
||||
return getTypedefType(CFConstantStringTypeDecl);
|
||||
return QualType();
|
||||
}
|
||||
void setCFConstantStringType(QualType T);
|
||||
TypedefDecl *getCFConstantStringDecl() const;
|
||||
RecordDecl *getCFConstantStringTagDecl() const;
|
||||
|
||||
// This setter/getter represents the ObjC type for an NSConstantString.
|
||||
void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
|
||||
|
|
@ -1458,12 +1465,25 @@ public:
|
|||
return NSCopyingName;
|
||||
}
|
||||
|
||||
/// Retrieve the identifier 'bool'.
|
||||
IdentifierInfo *getBoolName() const {
|
||||
if (!BoolName)
|
||||
BoolName = &Idents.get("bool");
|
||||
return BoolName;
|
||||
}
|
||||
|
||||
IdentifierInfo *getMakeIntegerSeqName() const {
|
||||
if (!MakeIntegerSeqName)
|
||||
MakeIntegerSeqName = &Idents.get("__make_integer_seq");
|
||||
return MakeIntegerSeqName;
|
||||
}
|
||||
|
||||
IdentifierInfo *getTypePackElementName() const {
|
||||
if (!TypePackElementName)
|
||||
TypePackElementName = &Idents.get("__type_pack_element");
|
||||
return TypePackElementName;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the Objective-C "instancetype" type, if already known;
|
||||
/// otherwise, returns a NULL type;
|
||||
QualType getObjCInstanceType() {
|
||||
|
|
@ -2257,7 +2277,7 @@ public:
|
|||
|
||||
QualType mergeObjCGCQualifiers(QualType, QualType);
|
||||
|
||||
bool FunctionTypesMatchOnNSConsumedAttrs(
|
||||
bool doFunctionTypesMatchOnExtParameterInfos(
|
||||
const FunctionProtoType *FromFunctionType,
|
||||
const FunctionProtoType *ToFunctionType);
|
||||
|
||||
|
|
@ -2508,7 +2528,21 @@ public:
|
|||
/// \brief Returns true if this is an inline-initialized static data member
|
||||
/// which is treated as a definition for MSVC compatibility.
|
||||
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
|
||||
|
||||
|
||||
enum class InlineVariableDefinitionKind {
|
||||
None, ///< Not an inline variable.
|
||||
Weak, ///< Weak definition of inline variable.
|
||||
WeakUnknown, ///< Weak for now, might become strong later in this TU.
|
||||
Strong ///< Strong definition.
|
||||
};
|
||||
/// \brief Determine whether a definition of this inline variable should
|
||||
/// be treated as a weak or strong definition. For compatibility with
|
||||
/// C++14 and before, for a constexpr static data member, if there is an
|
||||
/// out-of-line declaration of the member, we may promote it from weak to
|
||||
/// strong.
|
||||
InlineVariableDefinitionKind
|
||||
getInlineVariableDefinitionKind(const VarDecl *VD) const;
|
||||
|
||||
private:
|
||||
const ASTRecordLayout &
|
||||
getObjCLayout(const ObjCInterfaceDecl *D,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CXXCtorInitializer;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class DiagnosticsEngine;
|
||||
|
|
@ -204,6 +205,14 @@ namespace clang {
|
|||
/// \returns the equivalent file ID in the source manager of the "to"
|
||||
/// context.
|
||||
FileID Import(FileID);
|
||||
|
||||
/// \brief Import the given C++ constructor initializer from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent initializer in the "to" context.
|
||||
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
|
||||
|
||||
|
||||
|
||||
/// \brief Import the definition of the given declaration, including all of
|
||||
/// the declarations it contains.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace clang {
|
|||
class Attr;
|
||||
class ClassTemplateDecl;
|
||||
class ClassTemplateSpecializationDecl;
|
||||
class ConstructorUsingShadowDecl;
|
||||
class CXXDestructorDecl;
|
||||
class CXXRecordDecl;
|
||||
class Decl;
|
||||
|
|
@ -107,6 +108,14 @@ public:
|
|||
/// \param D the declaration marked OpenMP threadprivate.
|
||||
virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
|
||||
|
||||
/// \brief A declaration is marked as OpenMP declaretarget which was not
|
||||
/// previously marked as declaretarget.
|
||||
///
|
||||
/// \param D the declaration marked OpenMP declaretarget.
|
||||
/// \param Attr the added attribute.
|
||||
virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
|
||||
const Attr *Attr) {}
|
||||
|
||||
/// \brief A definition has been made visible by being redefined locally.
|
||||
///
|
||||
/// \param D The definition that was previously not visible.
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ public:
|
|||
/// \}
|
||||
|
||||
/// \brief Returns \c true if \c this and \c Other represent the same kind.
|
||||
bool isSame(ASTNodeKind Other) const;
|
||||
bool isSame(ASTNodeKind Other) const {
|
||||
return KindId != NKI_None && KindId == Other.KindId;
|
||||
}
|
||||
|
||||
/// \brief Returns \c true only for the default \c ASTNodeKind()
|
||||
bool isNone() const { return KindId == NKI_None; }
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/AttrKinds.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/OpenMPKinds.h"
|
||||
#include "clang/Basic/Sanitizers.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
|
|
@ -50,11 +51,11 @@ protected:
|
|||
/// An index into the spelling list of an
|
||||
/// attribute defined in Attr.td file.
|
||||
unsigned SpellingListIndex : 4;
|
||||
bool Inherited : 1;
|
||||
bool IsPackExpansion : 1;
|
||||
bool Implicit : 1;
|
||||
bool IsLateParsed : 1;
|
||||
bool DuplicatesAllowed : 1;
|
||||
unsigned Inherited : 1;
|
||||
unsigned IsPackExpansion : 1;
|
||||
unsigned Implicit : 1;
|
||||
unsigned IsLateParsed : 1;
|
||||
unsigned DuplicatesAllowed : 1;
|
||||
|
||||
void *operator new(size_t bytes) LLVM_NOEXCEPT {
|
||||
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
|
||||
|
|
@ -118,6 +119,19 @@ public:
|
|||
bool duplicatesAllowed() const { return DuplicatesAllowed; }
|
||||
};
|
||||
|
||||
class StmtAttr : public Attr {
|
||||
protected:
|
||||
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed, bool DuplicatesAllowed)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
|
||||
|
||||
public:
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() >= attr::FirstStmtAttr &&
|
||||
A->getKind() <= attr::LastStmtAttr;
|
||||
}
|
||||
};
|
||||
|
||||
class InheritableAttr : public Attr {
|
||||
protected:
|
||||
InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
|
|
@ -129,7 +143,8 @@ public:
|
|||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() <= attr::LAST_INHERITABLE;
|
||||
return A->getKind() >= attr::FirstInheritableAttr &&
|
||||
A->getKind() <= attr::LastInheritableAttr;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -143,12 +158,41 @@ protected:
|
|||
public:
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
// Relies on relative order of enum emission with respect to MS inheritance
|
||||
// attrs.
|
||||
return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
|
||||
return A->getKind() >= attr::FirstInheritableParamAttr &&
|
||||
A->getKind() <= attr::LastInheritableParamAttr;
|
||||
}
|
||||
};
|
||||
|
||||
/// A parameter attribute which changes the argument-passing ABI rule
|
||||
/// for the parameter.
|
||||
class ParameterABIAttr : public InheritableParamAttr {
|
||||
protected:
|
||||
ParameterABIAttr(attr::Kind AK, SourceRange R,
|
||||
unsigned SpellingListIndex, bool IsLateParsed,
|
||||
bool DuplicatesAllowed)
|
||||
: InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed,
|
||||
DuplicatesAllowed) {}
|
||||
|
||||
public:
|
||||
ParameterABI getABI() const {
|
||||
switch (getKind()) {
|
||||
case attr::SwiftContext:
|
||||
return ParameterABI::SwiftContext;
|
||||
case attr::SwiftErrorResult:
|
||||
return ParameterABI::SwiftErrorResult;
|
||||
case attr::SwiftIndirectResult:
|
||||
return ParameterABI::SwiftIndirectResult;
|
||||
default:
|
||||
llvm_unreachable("bad parameter ABI attribute kind");
|
||||
}
|
||||
}
|
||||
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() >= attr::FirstParameterABIAttr &&
|
||||
A->getKind() <= attr::LastParameterABIAttr;
|
||||
}
|
||||
};
|
||||
|
||||
#include "clang/AST/Attrs.inc"
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
|
|
|
|||
63
include/clang/AST/Availability.h
Normal file
63
include/clang/AST/Availability.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//===--- Availability.h - Classes for availability --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This files defines some classes that implement availability checking.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_AVAILABILITY_H
|
||||
#define LLVM_CLANG_AST_AVAILABILITY_H
|
||||
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief One specifier in an @available expression.
|
||||
///
|
||||
/// \code
|
||||
/// @available(macos 10.10, *)
|
||||
/// \endcode
|
||||
///
|
||||
/// Here, 'macos 10.10' and '*' both map to an instance of this type.
|
||||
///
|
||||
class AvailabilitySpec {
|
||||
/// Represents the version that this specifier requires. If the host OS
|
||||
/// version is greater than or equal to Version, the @available will evaluate
|
||||
/// to true.
|
||||
VersionTuple Version;
|
||||
|
||||
/// Name of the platform that Version corresponds to.
|
||||
StringRef Platform;
|
||||
|
||||
SourceLocation BeginLoc, EndLoc;
|
||||
|
||||
public:
|
||||
AvailabilitySpec(VersionTuple Version, StringRef Platform,
|
||||
SourceLocation BeginLoc, SourceLocation EndLoc)
|
||||
: Version(Version), Platform(Platform), BeginLoc(BeginLoc),
|
||||
EndLoc(EndLoc) {}
|
||||
|
||||
/// This constructor is used when representing the '*' case.
|
||||
AvailabilitySpec(SourceLocation StarLoc)
|
||||
: BeginLoc(StarLoc), EndLoc(StarLoc) {}
|
||||
|
||||
VersionTuple getVersion() const { return Version; }
|
||||
StringRef getPlatform() const { return Platform; }
|
||||
SourceLocation getBeginLoc() const { return BeginLoc; }
|
||||
SourceLocation getEndLoc() const { return EndLoc; }
|
||||
|
||||
/// Returns true when this represents the '*' case.
|
||||
bool isOtherPlatformSpec() const { return Version.empty(); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
@ -15,13 +15,12 @@
|
|||
#define LLVM_CLANG_AST_BASESUBOBJECT_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
||||
namespace clang {
|
||||
class CXXRecordDecl;
|
||||
|
||||
// BaseSubobject - Uniquely identifies a direct or indirect base class.
|
||||
// Stores both the base class decl and the offset from the most derived class to
|
||||
// the base class. Used for vtable and VTT generation.
|
||||
|
|
|
|||
|
|
@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
|
|||
// 'long double'
|
||||
FLOATING_TYPE(LongDouble, LongDoubleTy)
|
||||
|
||||
// '__float128'
|
||||
FLOATING_TYPE(Float128, Float128Ty)
|
||||
|
||||
//===- Language-specific types --------------------------------------------===//
|
||||
|
||||
// This is the type of C++0x 'nullptr'.
|
||||
|
|
@ -154,20 +157,6 @@ BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
|
|||
// type is a typedef of a PointerType to this.
|
||||
BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
|
||||
|
||||
// OpenCL image types.
|
||||
BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
|
||||
BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
|
||||
BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
|
||||
BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
|
||||
BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
|
||||
BUILTIN_TYPE(OCLImage2dDepth, OCLImage2dDepthTy)
|
||||
BUILTIN_TYPE(OCLImage2dArrayDepth, OCLImage2dArrayDepthTy)
|
||||
BUILTIN_TYPE(OCLImage2dMSAA, OCLImage2dMSAATy)
|
||||
BUILTIN_TYPE(OCLImage2dArrayMSAA, OCLImage2dArrayMSAATy)
|
||||
BUILTIN_TYPE(OCLImage2dMSAADepth, OCLImage2dMSAADepthTy)
|
||||
BUILTIN_TYPE(OCLImage2dArrayMSAADepth, OCLImage2dArrayMSAADepthTy)
|
||||
BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
|
||||
|
||||
// OpenCL sampler_t.
|
||||
BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
|
||||
|
||||
|
|
|
|||
|
|
@ -484,6 +484,9 @@ struct CanProxyAdaptor<FunctionProtoType>
|
|||
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
|
||||
ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
|
||||
CanQualType getParamType(unsigned i) const {
|
||||
return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ namespace clang {
|
|||
/// Test whether this is a multiple of the other value.
|
||||
///
|
||||
/// Among other things, this promises that
|
||||
/// self.RoundUpToAlignment(N) will just return self.
|
||||
/// self.alignTo(N) will just return self.
|
||||
bool isMultipleOf(CharUnits N) const {
|
||||
return (*this % N) == 0;
|
||||
}
|
||||
|
|
@ -142,9 +142,17 @@ namespace clang {
|
|||
CharUnits operator* (QuantityType N) const {
|
||||
return CharUnits(Quantity * N);
|
||||
}
|
||||
CharUnits &operator*= (QuantityType N) {
|
||||
Quantity *= N;
|
||||
return *this;
|
||||
}
|
||||
CharUnits operator/ (QuantityType N) const {
|
||||
return CharUnits(Quantity / N);
|
||||
}
|
||||
CharUnits &operator/= (QuantityType N) {
|
||||
Quantity /= N;
|
||||
return *this;
|
||||
}
|
||||
QuantityType operator/ (const CharUnits &Other) const {
|
||||
return Quantity / Other.Quantity;
|
||||
}
|
||||
|
|
@ -170,12 +178,11 @@ namespace clang {
|
|||
/// getQuantity - Get the raw integer representation of this quantity.
|
||||
QuantityType getQuantity() const { return Quantity; }
|
||||
|
||||
/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
|
||||
/// alignTo - Returns the next integer (mod 2**64) that is
|
||||
/// greater than or equal to this quantity and is a multiple of \p Align.
|
||||
/// Align must be non-zero.
|
||||
CharUnits RoundUpToAlignment(const CharUnits &Align) const {
|
||||
return CharUnits(llvm::RoundUpToAlignment(Quantity,
|
||||
Align.Quantity));
|
||||
CharUnits alignTo(const CharUnits &Align) const {
|
||||
return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
|
||||
}
|
||||
|
||||
/// Given that this is a non-zero alignment value, what is the
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "clang/Basic/Linkage.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Basic/PragmaKinds.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
|
@ -103,6 +104,73 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a `#pragma comment` line. Always a child of
|
||||
/// TranslationUnitDecl.
|
||||
class PragmaCommentDecl final
|
||||
: public Decl,
|
||||
private llvm::TrailingObjects<PragmaCommentDecl, char> {
|
||||
virtual void anchor();
|
||||
|
||||
PragmaMSCommentKind CommentKind;
|
||||
|
||||
friend TrailingObjects;
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
|
||||
PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc,
|
||||
PragmaMSCommentKind CommentKind)
|
||||
: Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {}
|
||||
|
||||
public:
|
||||
static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC,
|
||||
SourceLocation CommentLoc,
|
||||
PragmaMSCommentKind CommentKind,
|
||||
StringRef Arg);
|
||||
static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID,
|
||||
unsigned ArgSize);
|
||||
|
||||
PragmaMSCommentKind getCommentKind() const { return CommentKind; }
|
||||
|
||||
StringRef getArg() const { return getTrailingObjects<char>(); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == PragmaComment; }
|
||||
};
|
||||
|
||||
/// \brief Represents a `#pragma detect_mismatch` line. Always a child of
|
||||
/// TranslationUnitDecl.
|
||||
class PragmaDetectMismatchDecl final
|
||||
: public Decl,
|
||||
private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> {
|
||||
virtual void anchor();
|
||||
|
||||
size_t ValueStart;
|
||||
|
||||
friend TrailingObjects;
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
|
||||
PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc,
|
||||
size_t ValueStart)
|
||||
: Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {}
|
||||
|
||||
public:
|
||||
static PragmaDetectMismatchDecl *Create(const ASTContext &C,
|
||||
TranslationUnitDecl *DC,
|
||||
SourceLocation Loc, StringRef Name,
|
||||
StringRef Value);
|
||||
static PragmaDetectMismatchDecl *
|
||||
CreateDeserialized(ASTContext &C, unsigned ID, unsigned NameValueSize);
|
||||
|
||||
StringRef getName() const { return getTrailingObjects<char>(); }
|
||||
StringRef getValue() const { return getTrailingObjects<char>() + ValueStart; }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == PragmaDetectMismatch; }
|
||||
};
|
||||
|
||||
/// \brief Declaration context for names declared as extern "C" in C++. This
|
||||
/// is neither the semantic nor lexical context for such declarations, but is
|
||||
/// used to check for conflicts with other extern "C" declarations. Example:
|
||||
|
|
@ -319,6 +387,7 @@ public:
|
|||
NamedDecl *getUnderlyingDecl() {
|
||||
// Fast-path the common case.
|
||||
if (this->getKind() != UsingShadow &&
|
||||
this->getKind() != ConstructorUsingShadow &&
|
||||
this->getKind() != ObjCCompatibleAlias &&
|
||||
this->getKind() != NamespaceAlias)
|
||||
return this;
|
||||
|
|
@ -813,12 +882,15 @@ protected:
|
|||
/// variable; see isARCPseudoStrong() for details.
|
||||
unsigned ARCPseudoStrong : 1;
|
||||
|
||||
/// \brief Whether this variable is (C++1z) inline.
|
||||
unsigned IsInline : 1;
|
||||
|
||||
/// \brief Whether this variable has (C++1z) inline explicitly specified.
|
||||
unsigned IsInlineSpecified : 1;
|
||||
|
||||
/// \brief Whether this variable is (C++0x) constexpr.
|
||||
unsigned IsConstexpr : 1;
|
||||
|
||||
/// \brief Whether this variable is a (C++ Concepts TS) concept.
|
||||
unsigned IsConcept : 1;
|
||||
|
||||
/// \brief Whether this variable is the implicit variable for a lambda
|
||||
/// init-capture.
|
||||
unsigned IsInitCapture : 1;
|
||||
|
|
@ -1037,9 +1109,6 @@ public:
|
|||
/// definition of a static data member.
|
||||
bool isOutOfLine() const override;
|
||||
|
||||
/// \brief If this is a static data member, find its out-of-line definition.
|
||||
VarDecl *getOutOfLineDefinition();
|
||||
|
||||
/// isFileVarDecl - Returns true for file scoped variable declaration.
|
||||
bool isFileVarDecl() const {
|
||||
Kind K = getKind();
|
||||
|
|
@ -1185,6 +1254,24 @@ public:
|
|||
NonParmVarDeclBits.ARCPseudoStrong = ps;
|
||||
}
|
||||
|
||||
/// Whether this variable is (C++1z) inline.
|
||||
bool isInline() const {
|
||||
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInline;
|
||||
}
|
||||
bool isInlineSpecified() const {
|
||||
return isa<ParmVarDecl>(this) ? false
|
||||
: NonParmVarDeclBits.IsInlineSpecified;
|
||||
}
|
||||
void setInlineSpecified() {
|
||||
assert(!isa<ParmVarDecl>(this));
|
||||
NonParmVarDeclBits.IsInline = true;
|
||||
NonParmVarDeclBits.IsInlineSpecified = true;
|
||||
}
|
||||
void setImplicitlyInline() {
|
||||
assert(!isa<ParmVarDecl>(this));
|
||||
NonParmVarDeclBits.IsInline = true;
|
||||
}
|
||||
|
||||
/// Whether this variable is (C++11) constexpr.
|
||||
bool isConstexpr() const {
|
||||
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr;
|
||||
|
|
@ -1194,15 +1281,6 @@ public:
|
|||
NonParmVarDeclBits.IsConstexpr = IC;
|
||||
}
|
||||
|
||||
/// Whether this variable is (C++ Concepts TS) concept.
|
||||
bool isConcept() const {
|
||||
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept;
|
||||
}
|
||||
void setConcept(bool IC) {
|
||||
assert(!isa<ParmVarDecl>(this));
|
||||
NonParmVarDeclBits.IsConcept = IC;
|
||||
}
|
||||
|
||||
/// Whether this variable is the implicit variable for a lambda init-capture.
|
||||
bool isInitCapture() const {
|
||||
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
|
||||
|
|
@ -1702,6 +1780,17 @@ public:
|
|||
return isDefined(Definition);
|
||||
}
|
||||
|
||||
/// \brief Get the definition for this declaration.
|
||||
FunctionDecl *getDefinition() {
|
||||
const FunctionDecl *Definition;
|
||||
if (isDefined(Definition))
|
||||
return const_cast<FunctionDecl *>(Definition);
|
||||
return nullptr;
|
||||
}
|
||||
const FunctionDecl *getDefinition() const {
|
||||
return const_cast<FunctionDecl *>(this)->getDefinition();
|
||||
}
|
||||
|
||||
/// getBody - Retrieve the body (definition) of the function. The
|
||||
/// function body might be in any of the (re-)declarations of this
|
||||
/// function. The variant that accepts a FunctionDecl pointer will
|
||||
|
|
@ -1896,28 +1985,23 @@ public:
|
|||
|
||||
unsigned getBuiltinID() const;
|
||||
|
||||
// ArrayRef interface to parameters.
|
||||
ArrayRef<ParmVarDecl *> parameters() const {
|
||||
return {ParamInfo, getNumParams()};
|
||||
}
|
||||
MutableArrayRef<ParmVarDecl *> parameters() {
|
||||
return {ParamInfo, getNumParams()};
|
||||
}
|
||||
|
||||
// Iterator access to formal parameters.
|
||||
unsigned param_size() const { return getNumParams(); }
|
||||
typedef ParmVarDecl **param_iterator;
|
||||
typedef ParmVarDecl * const *param_const_iterator;
|
||||
typedef llvm::iterator_range<param_iterator> param_range;
|
||||
typedef llvm::iterator_range<param_const_iterator> param_const_range;
|
||||
|
||||
param_iterator param_begin() { return param_iterator(ParamInfo); }
|
||||
param_iterator param_end() {
|
||||
return param_iterator(ParamInfo + param_size());
|
||||
}
|
||||
param_range params() { return param_range(param_begin(), param_end()); }
|
||||
|
||||
param_const_iterator param_begin() const {
|
||||
return param_const_iterator(ParamInfo);
|
||||
}
|
||||
param_const_iterator param_end() const {
|
||||
return param_const_iterator(ParamInfo + param_size());
|
||||
}
|
||||
param_const_range params() const {
|
||||
return param_const_range(param_begin(), param_end());
|
||||
}
|
||||
typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator;
|
||||
typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator;
|
||||
bool param_empty() const { return parameters().empty(); }
|
||||
param_iterator param_begin() { return parameters().begin(); }
|
||||
param_iterator param_end() { return parameters().end(); }
|
||||
param_const_iterator param_begin() const { return parameters().begin(); }
|
||||
param_const_iterator param_end() const { return parameters().end(); }
|
||||
size_t param_size() const { return parameters().size(); }
|
||||
|
||||
/// getNumParams - Return the number of parameters this function must have
|
||||
/// based on its FunctionType. This is the length of the ParamInfo array
|
||||
|
|
@ -1936,12 +2020,6 @@ public:
|
|||
setParams(getASTContext(), NewParamInfo);
|
||||
}
|
||||
|
||||
// ArrayRef iterface to parameters.
|
||||
// FIXME: Should one day replace iterator interface.
|
||||
ArrayRef<ParmVarDecl*> parameters() const {
|
||||
return llvm::makeArrayRef(ParamInfo, getNumParams());
|
||||
}
|
||||
|
||||
ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
|
||||
return DeclsInPrototypeScope;
|
||||
}
|
||||
|
|
@ -1954,6 +2032,7 @@ public:
|
|||
unsigned getMinRequiredArguments() const;
|
||||
|
||||
QualType getReturnType() const {
|
||||
assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
|
||||
return getType()->getAs<FunctionType>()->getReturnType();
|
||||
}
|
||||
|
||||
|
|
@ -1964,15 +2043,20 @@ public:
|
|||
|
||||
/// \brief Determine the type of an expression that calls this function.
|
||||
QualType getCallResultType() const {
|
||||
assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
|
||||
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
|
||||
}
|
||||
|
||||
/// \brief Returns the WarnUnusedResultAttr that is either declared on this
|
||||
/// function, or its return type declaration.
|
||||
const Attr *getUnusedResultAttr() const;
|
||||
|
||||
/// \brief Returns true if this function or its return type has the
|
||||
/// warn_unused_result attribute. If the return type has the attribute and
|
||||
/// this function is a method of the return type's class, then false will be
|
||||
/// returned to avoid spurious warnings on member methods such as assignment
|
||||
/// operators.
|
||||
bool hasUnusedResultAttr() const;
|
||||
bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
|
||||
|
||||
/// \brief Returns the storage class as written in the source. For the
|
||||
/// computed linkage of symbol, see getLinkage.
|
||||
|
|
@ -2208,7 +2292,7 @@ public:
|
|||
/// represent a member of a struct/union/class.
|
||||
class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
|
||||
// FIXME: This can be packed into the bitfields in Decl.
|
||||
bool Mutable : 1;
|
||||
unsigned Mutable : 1;
|
||||
mutable unsigned CachedFieldIndex : 31;
|
||||
|
||||
/// The kinds of value we can store in InitializerOrBitWidth.
|
||||
|
|
@ -2442,34 +2526,33 @@ class IndirectFieldDecl : public ValueDecl,
|
|||
|
||||
IndirectFieldDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName N, QualType T,
|
||||
NamedDecl **CH, unsigned CHS);
|
||||
MutableArrayRef<NamedDecl *> CH);
|
||||
|
||||
public:
|
||||
static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
QualType T, NamedDecl **CH, unsigned CHS);
|
||||
QualType T, llvm::MutableArrayRef<NamedDecl *> CH);
|
||||
|
||||
static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
typedef NamedDecl * const *chain_iterator;
|
||||
typedef llvm::iterator_range<chain_iterator> chain_range;
|
||||
|
||||
chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
|
||||
chain_iterator chain_begin() const { return chain_iterator(Chaining); }
|
||||
chain_iterator chain_end() const {
|
||||
return chain_iterator(Chaining + ChainingSize);
|
||||
typedef ArrayRef<NamedDecl *>::const_iterator chain_iterator;
|
||||
|
||||
ArrayRef<NamedDecl *> chain() const {
|
||||
return llvm::makeArrayRef(Chaining, ChainingSize);
|
||||
}
|
||||
chain_iterator chain_begin() const { return chain().begin(); }
|
||||
chain_iterator chain_end() const { return chain().end(); }
|
||||
|
||||
unsigned getChainingSize() const { return ChainingSize; }
|
||||
|
||||
FieldDecl *getAnonField() const {
|
||||
assert(ChainingSize >= 2);
|
||||
return cast<FieldDecl>(Chaining[ChainingSize - 1]);
|
||||
assert(chain().size() >= 2);
|
||||
return cast<FieldDecl>(chain().back());
|
||||
}
|
||||
|
||||
VarDecl *getVarDecl() const {
|
||||
assert(ChainingSize >= 2);
|
||||
return dyn_cast<VarDecl>(*chain_begin());
|
||||
assert(chain().size() >= 2);
|
||||
return dyn_cast<VarDecl>(chain().front());
|
||||
}
|
||||
|
||||
IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
|
||||
|
|
@ -2655,20 +2738,20 @@ private:
|
|||
/// IsCompleteDefinition - True if this is a definition ("struct foo
|
||||
/// {};"), false if it is a declaration ("struct foo;"). It is not
|
||||
/// a definition until the definition has been fully processed.
|
||||
bool IsCompleteDefinition : 1;
|
||||
unsigned IsCompleteDefinition : 1;
|
||||
|
||||
protected:
|
||||
/// IsBeingDefined - True if this is currently being defined.
|
||||
bool IsBeingDefined : 1;
|
||||
unsigned IsBeingDefined : 1;
|
||||
|
||||
private:
|
||||
/// IsEmbeddedInDeclarator - True if this tag declaration is
|
||||
/// "embedded" (i.e., defined or declared for the very first time)
|
||||
/// in the syntax of a declarator.
|
||||
bool IsEmbeddedInDeclarator : 1;
|
||||
unsigned IsEmbeddedInDeclarator : 1;
|
||||
|
||||
/// \brief True if this tag is free standing, e.g. "struct foo;".
|
||||
bool IsFreeStanding : 1;
|
||||
unsigned IsFreeStanding : 1;
|
||||
|
||||
protected:
|
||||
// These are used by (and only defined for) EnumDecl.
|
||||
|
|
@ -2677,28 +2760,28 @@ protected:
|
|||
|
||||
/// IsScoped - True if this tag declaration is a scoped enumeration. Only
|
||||
/// possible in C++11 mode.
|
||||
bool IsScoped : 1;
|
||||
unsigned IsScoped : 1;
|
||||
/// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
|
||||
/// then this is true if the scoped enum was declared using the class
|
||||
/// tag, false if it was declared with the struct tag. No meaning is
|
||||
/// associated if this tag declaration is not a scoped enum.
|
||||
bool IsScopedUsingClassTag : 1;
|
||||
unsigned IsScopedUsingClassTag : 1;
|
||||
|
||||
/// IsFixed - True if this is an enumeration with fixed underlying type. Only
|
||||
/// possible in C++11, Microsoft extensions, or Objective C mode.
|
||||
bool IsFixed : 1;
|
||||
unsigned IsFixed : 1;
|
||||
|
||||
/// \brief Indicates whether it is possible for declarations of this kind
|
||||
/// to have an out-of-date definition.
|
||||
///
|
||||
/// This option is only enabled when modules are enabled.
|
||||
bool MayHaveOutOfDateDef : 1;
|
||||
unsigned MayHaveOutOfDateDef : 1;
|
||||
|
||||
/// Has the full definition of this type been required by a use somewhere in
|
||||
/// the TU.
|
||||
bool IsCompleteDefinitionRequired : 1;
|
||||
unsigned IsCompleteDefinitionRequired : 1;
|
||||
private:
|
||||
SourceLocation RBraceLoc;
|
||||
SourceRange BraceRange;
|
||||
|
||||
// A struct representing syntactic qualifier info,
|
||||
// to be used for the (uncommon) case of out-of-line declarations.
|
||||
|
|
@ -2760,8 +2843,8 @@ public:
|
|||
using redeclarable_base::getMostRecentDecl;
|
||||
using redeclarable_base::isFirstDecl;
|
||||
|
||||
SourceLocation getRBraceLoc() const { return RBraceLoc; }
|
||||
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
|
||||
SourceRange getBraceRange() const { return BraceRange; }
|
||||
void setBraceRange(SourceRange R) { BraceRange = R; }
|
||||
|
||||
/// getInnerLocStart - Return SourceLocation representing start of source
|
||||
/// range ignoring outer template declarations.
|
||||
|
|
@ -3122,6 +3205,10 @@ public:
|
|||
return isCompleteDefinition() || isFixed();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the enum definition from which this enumeration could
|
||||
/// be instantiated, if it is an instantiation (rather than a non-template).
|
||||
EnumDecl *getTemplateInstantiationPattern() const;
|
||||
|
||||
/// \brief Returns the enumeration (declared within the template)
|
||||
/// from which this enumeration type was instantiated, or NULL if
|
||||
/// this enumeration was not instantiated from any template.
|
||||
|
|
@ -3452,35 +3539,23 @@ public:
|
|||
void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
|
||||
TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
|
||||
|
||||
// Iterator access to formal parameters.
|
||||
unsigned param_size() const { return getNumParams(); }
|
||||
typedef ParmVarDecl **param_iterator;
|
||||
typedef ParmVarDecl * const *param_const_iterator;
|
||||
typedef llvm::iterator_range<param_iterator> param_range;
|
||||
typedef llvm::iterator_range<param_const_iterator> param_const_range;
|
||||
|
||||
// ArrayRef access to formal parameters.
|
||||
// FIXME: Should eventual replace iterator access.
|
||||
ArrayRef<ParmVarDecl*> parameters() const {
|
||||
return llvm::makeArrayRef(ParamInfo, param_size());
|
||||
ArrayRef<ParmVarDecl *> parameters() const {
|
||||
return {ParamInfo, getNumParams()};
|
||||
}
|
||||
MutableArrayRef<ParmVarDecl *> parameters() {
|
||||
return {ParamInfo, getNumParams()};
|
||||
}
|
||||
|
||||
bool param_empty() const { return NumParams == 0; }
|
||||
param_range params() { return param_range(param_begin(), param_end()); }
|
||||
param_iterator param_begin() { return param_iterator(ParamInfo); }
|
||||
param_iterator param_end() {
|
||||
return param_iterator(ParamInfo + param_size());
|
||||
}
|
||||
|
||||
param_const_range params() const {
|
||||
return param_const_range(param_begin(), param_end());
|
||||
}
|
||||
param_const_iterator param_begin() const {
|
||||
return param_const_iterator(ParamInfo);
|
||||
}
|
||||
param_const_iterator param_end() const {
|
||||
return param_const_iterator(ParamInfo + param_size());
|
||||
}
|
||||
// Iterator access to formal parameters.
|
||||
typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator;
|
||||
typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator;
|
||||
bool param_empty() const { return parameters().empty(); }
|
||||
param_iterator param_begin() { return parameters().begin(); }
|
||||
param_iterator param_end() { return parameters().end(); }
|
||||
param_const_iterator param_begin() const { return parameters().begin(); }
|
||||
param_const_iterator param_end() const { return parameters().end(); }
|
||||
size_t param_size() const { return parameters().size(); }
|
||||
|
||||
unsigned getNumParams() const { return NumParams; }
|
||||
const ParmVarDecl *getParamDecl(unsigned i) const {
|
||||
|
|
@ -3501,22 +3576,12 @@ public:
|
|||
/// Does not include an entry for 'this'.
|
||||
unsigned getNumCaptures() const { return NumCaptures; }
|
||||
|
||||
typedef const Capture *capture_iterator;
|
||||
typedef const Capture *capture_const_iterator;
|
||||
typedef llvm::iterator_range<capture_iterator> capture_range;
|
||||
typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
|
||||
typedef ArrayRef<Capture>::const_iterator capture_const_iterator;
|
||||
|
||||
capture_range captures() {
|
||||
return capture_range(capture_begin(), capture_end());
|
||||
}
|
||||
capture_const_range captures() const {
|
||||
return capture_const_range(capture_begin(), capture_end());
|
||||
}
|
||||
ArrayRef<Capture> captures() const { return {Captures, NumCaptures}; }
|
||||
|
||||
capture_iterator capture_begin() { return Captures; }
|
||||
capture_iterator capture_end() { return Captures + NumCaptures; }
|
||||
capture_const_iterator capture_begin() const { return Captures; }
|
||||
capture_const_iterator capture_end() const { return Captures + NumCaptures; }
|
||||
capture_const_iterator capture_begin() const { return captures().begin(); }
|
||||
capture_const_iterator capture_end() const { return captures().end(); }
|
||||
|
||||
bool capturesCXXThis() const { return CapturesCXXThis; }
|
||||
bool blockMissingReturnType() const { return BlockMissingReturnType; }
|
||||
|
|
@ -3607,6 +3672,14 @@ public:
|
|||
getParams()[i] = P;
|
||||
}
|
||||
|
||||
// ArrayRef interface to parameters.
|
||||
ArrayRef<ImplicitParamDecl *> parameters() const {
|
||||
return {getParams(), getNumParams()};
|
||||
}
|
||||
MutableArrayRef<ImplicitParamDecl *> parameters() {
|
||||
return {getParams(), getNumParams()};
|
||||
}
|
||||
|
||||
/// \brief Retrieve the parameter containing captured variables.
|
||||
ImplicitParamDecl *getContextParam() const {
|
||||
assert(ContextParam < NumParams);
|
||||
|
|
@ -3627,9 +3700,6 @@ public:
|
|||
/// \brief Retrieve an iterator one past the last parameter decl.
|
||||
param_iterator param_end() const { return getParams() + NumParams; }
|
||||
|
||||
/// \brief Retrieve an iterator range for the parameter declarations.
|
||||
param_range params() const { return param_range(param_begin(), param_end()); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == Captured; }
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ struct PrintingPolicy;
|
|||
class RecordDecl;
|
||||
class Stmt;
|
||||
class StoredDeclsMap;
|
||||
class TemplateDecl;
|
||||
class TranslationUnitDecl;
|
||||
class UsingDirectiveDecl;
|
||||
}
|
||||
|
|
@ -72,13 +73,10 @@ namespace clang {
|
|||
///
|
||||
/// Note: There are objects tacked on before the *beginning* of Decl
|
||||
/// (and its subclasses) in its Decl::operator new(). Proper alignment
|
||||
/// of all subclasses (not requiring more than DeclObjAlignment) is
|
||||
/// of all subclasses (not requiring more than the alignment of Decl) is
|
||||
/// asserted in DeclBase.cpp.
|
||||
class Decl {
|
||||
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
public:
|
||||
/// \brief Alignment guaranteed when allocating Decl and any subtypes.
|
||||
enum { DeclObjAlignment = llvm::AlignOf<uint64_t>::Alignment };
|
||||
|
||||
/// \brief Lists the kind of concrete classes of Decl.
|
||||
enum Kind {
|
||||
#define DECL(DERIVED, BASE) DERIVED,
|
||||
|
|
@ -166,7 +164,10 @@ public:
|
|||
/// has been declared outside any function. These act mostly like
|
||||
/// invisible friend declarations, but are also visible to unqualified
|
||||
/// lookup within the scope of the declaring function.
|
||||
IDNS_LocalExtern = 0x0800
|
||||
IDNS_LocalExtern = 0x0800,
|
||||
|
||||
/// This declaration is an OpenMP user defined reduction construction.
|
||||
IDNS_OMPReduction = 0x1000
|
||||
};
|
||||
|
||||
/// ObjCDeclQualifier - 'Qualifiers' written next to the return and
|
||||
|
|
@ -256,7 +257,7 @@ private:
|
|||
SourceLocation Loc;
|
||||
|
||||
/// DeclKind - This indicates which class this is.
|
||||
unsigned DeclKind : 8;
|
||||
unsigned DeclKind : 7;
|
||||
|
||||
/// InvalidDecl - This indicates a semantic error occurred.
|
||||
unsigned InvalidDecl : 1;
|
||||
|
|
@ -296,7 +297,7 @@ protected:
|
|||
unsigned Hidden : 1;
|
||||
|
||||
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
|
||||
unsigned IdentifierNamespace : 12;
|
||||
unsigned IdentifierNamespace : 13;
|
||||
|
||||
/// \brief If 0, we have not computed the linkage of this declaration.
|
||||
/// Otherwise, it is the linkage + 1.
|
||||
|
|
@ -514,8 +515,8 @@ public:
|
|||
bool isImplicit() const { return Implicit; }
|
||||
void setImplicit(bool I = true) { Implicit = I; }
|
||||
|
||||
/// \brief Whether this declaration was used, meaning that a definition
|
||||
/// is required.
|
||||
/// \brief Whether *any* (re-)declaration of the entity was used, meaning that
|
||||
/// a definition is required.
|
||||
///
|
||||
/// \param CheckUsedAttr When true, also consider the "used" attribute
|
||||
/// (in addition to the "used" bit set by \c setUsed()) when determining
|
||||
|
|
@ -525,7 +526,8 @@ public:
|
|||
/// \brief Set whether the declaration is used, in the sense of odr-use.
|
||||
///
|
||||
/// This should only be used immediately after creating a declaration.
|
||||
void setIsUsed() { Used = true; }
|
||||
/// It intentionally doesn't notify any listeners.
|
||||
void setIsUsed() { getCanonicalDecl()->Used = true; }
|
||||
|
||||
/// \brief Mark the declaration used, in the sense of odr-use.
|
||||
///
|
||||
|
|
@ -564,6 +566,13 @@ public:
|
|||
return NextInContextAndBits.getInt() & ModulePrivateFlag;
|
||||
}
|
||||
|
||||
/// Return true if this declaration has an attribute which acts as
|
||||
/// definition of the entity, such as 'alias' or 'ifunc'.
|
||||
bool hasDefiningAttr() const;
|
||||
|
||||
/// Return this declaration's defining attribute if it has one.
|
||||
const Attr *getDefiningAttr() const;
|
||||
|
||||
protected:
|
||||
/// \brief Specify whether this declaration was marked as being private
|
||||
/// to the module in which it was defined.
|
||||
|
|
@ -895,6 +904,10 @@ public:
|
|||
DeclKind == FunctionTemplate;
|
||||
}
|
||||
|
||||
/// \brief If this is a declaration that describes some template, this
|
||||
/// method returns that template declaration.
|
||||
TemplateDecl *getDescribedTemplate() const;
|
||||
|
||||
/// \brief Returns the function itself, or the templated function if this is a
|
||||
/// function template.
|
||||
FunctionDecl *getAsFunction() LLVM_READONLY;
|
||||
|
|
@ -1117,6 +1130,7 @@ public:
|
|||
/// ObjCContainerDecl
|
||||
/// LinkageSpecDecl
|
||||
/// BlockDecl
|
||||
/// OMPDeclareReductionDecl
|
||||
///
|
||||
class DeclContext {
|
||||
/// DeclKind - This indicates which class this is.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#ifndef LLVM_CLANG_AST_DECLCXX_H
|
||||
#define LLVM_CLANG_AST_DECLCXX_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTUnresolvedSet.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
|
|
@ -29,6 +30,7 @@ namespace clang {
|
|||
|
||||
class ClassTemplateDecl;
|
||||
class ClassTemplateSpecializationDecl;
|
||||
class ConstructorUsingShadowDecl;
|
||||
class CXXBasePath;
|
||||
class CXXBasePaths;
|
||||
class CXXConstructorDecl;
|
||||
|
|
@ -165,13 +167,13 @@ class CXXBaseSpecifier {
|
|||
SourceLocation EllipsisLoc;
|
||||
|
||||
/// \brief Whether this is a virtual base class or not.
|
||||
bool Virtual : 1;
|
||||
unsigned Virtual : 1;
|
||||
|
||||
/// \brief Whether this is the base of a class (true) or of a struct (false).
|
||||
///
|
||||
/// This determines the mapping from the access specifier as written in the
|
||||
/// source code to the access specifier used for semantic analysis.
|
||||
bool BaseOfClass : 1;
|
||||
unsigned BaseOfClass : 1;
|
||||
|
||||
/// \brief Access specifier as written in the source code (may be AS_none).
|
||||
///
|
||||
|
|
@ -181,7 +183,7 @@ class CXXBaseSpecifier {
|
|||
|
||||
/// \brief Whether the class contains a using declaration
|
||||
/// to inherit the named class's constructors.
|
||||
bool InheritConstructors : 1;
|
||||
unsigned InheritConstructors : 1;
|
||||
|
||||
/// \brief The type of the base class.
|
||||
///
|
||||
|
|
@ -257,30 +259,6 @@ public:
|
|||
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
|
||||
};
|
||||
|
||||
/// \brief A lazy pointer to the definition data for a declaration.
|
||||
/// FIXME: This is a little CXXRecordDecl-specific that the moment.
|
||||
template<typename Decl, typename T> class LazyDefinitionDataPtr {
|
||||
llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
|
||||
|
||||
LazyDefinitionDataPtr update() {
|
||||
if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
|
||||
if (Canon->isCanonicalDecl())
|
||||
Canon->getMostRecentDecl();
|
||||
else
|
||||
// Declaration isn't canonical any more;
|
||||
// update it and perform path compression.
|
||||
*this = Canon->getPreviousDecl()->DefinitionData.update();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
|
||||
LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
|
||||
T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
|
||||
T *get() { return update().getNotUpdated(); }
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ struct/union/class.
|
||||
class CXXRecordDecl : public RecordDecl {
|
||||
|
||||
|
|
@ -301,30 +279,30 @@ class CXXRecordDecl : public RecordDecl {
|
|||
DefinitionData(CXXRecordDecl *D);
|
||||
|
||||
/// \brief True if this class has any user-declared constructors.
|
||||
bool UserDeclaredConstructor : 1;
|
||||
unsigned UserDeclaredConstructor : 1;
|
||||
|
||||
/// \brief The user-declared special members which this class has.
|
||||
unsigned UserDeclaredSpecialMembers : 6;
|
||||
|
||||
/// \brief True when this class is an aggregate.
|
||||
bool Aggregate : 1;
|
||||
unsigned Aggregate : 1;
|
||||
|
||||
/// \brief True when this class is a POD-type.
|
||||
bool PlainOldData : 1;
|
||||
unsigned PlainOldData : 1;
|
||||
|
||||
/// true when this class is empty for traits purposes,
|
||||
/// i.e. has no data members other than 0-width bit-fields, has no
|
||||
/// virtual function/base, and doesn't inherit from a non-empty
|
||||
/// class. Doesn't take union-ness into account.
|
||||
bool Empty : 1;
|
||||
unsigned Empty : 1;
|
||||
|
||||
/// \brief True when this class is polymorphic, i.e., has at
|
||||
/// least one virtual member or derives from a polymorphic class.
|
||||
bool Polymorphic : 1;
|
||||
unsigned Polymorphic : 1;
|
||||
|
||||
/// \brief True when this class is abstract, i.e., has at least
|
||||
/// one pure virtual function, (that can come from a base class).
|
||||
bool Abstract : 1;
|
||||
unsigned Abstract : 1;
|
||||
|
||||
/// \brief True when this class has standard layout.
|
||||
///
|
||||
|
|
@ -340,58 +318,70 @@ class CXXRecordDecl : public RecordDecl {
|
|||
/// classes with non-static data members, and
|
||||
/// * has no base classes of the same type as the first non-static data
|
||||
/// member.
|
||||
bool IsStandardLayout : 1;
|
||||
unsigned IsStandardLayout : 1;
|
||||
|
||||
/// \brief True when there are no non-empty base classes.
|
||||
///
|
||||
/// This is a helper bit of state used to implement IsStandardLayout more
|
||||
/// efficiently.
|
||||
bool HasNoNonEmptyBases : 1;
|
||||
unsigned HasNoNonEmptyBases : 1;
|
||||
|
||||
/// \brief True when there are private non-static data members.
|
||||
bool HasPrivateFields : 1;
|
||||
unsigned HasPrivateFields : 1;
|
||||
|
||||
/// \brief True when there are protected non-static data members.
|
||||
bool HasProtectedFields : 1;
|
||||
unsigned HasProtectedFields : 1;
|
||||
|
||||
/// \brief True when there are private non-static data members.
|
||||
bool HasPublicFields : 1;
|
||||
unsigned HasPublicFields : 1;
|
||||
|
||||
/// \brief True if this class (or any subobject) has mutable fields.
|
||||
bool HasMutableFields : 1;
|
||||
unsigned HasMutableFields : 1;
|
||||
|
||||
/// \brief True if this class (or any nested anonymous struct or union)
|
||||
/// has variant members.
|
||||
bool HasVariantMembers : 1;
|
||||
unsigned HasVariantMembers : 1;
|
||||
|
||||
/// \brief True if there no non-field members declared by the user.
|
||||
bool HasOnlyCMembers : 1;
|
||||
unsigned HasOnlyCMembers : 1;
|
||||
|
||||
/// \brief True if any field has an in-class initializer, including those
|
||||
/// within anonymous unions or structs.
|
||||
bool HasInClassInitializer : 1;
|
||||
unsigned HasInClassInitializer : 1;
|
||||
|
||||
/// \brief True if any field is of reference type, and does not have an
|
||||
/// in-class initializer.
|
||||
///
|
||||
/// In this case, value-initialization of this class is illegal in C++98
|
||||
/// even if the class has a trivial default constructor.
|
||||
bool HasUninitializedReferenceMember : 1;
|
||||
unsigned HasUninitializedReferenceMember : 1;
|
||||
|
||||
/// \brief True if any non-mutable field whose type doesn't have a user-
|
||||
/// provided default ctor also doesn't have an in-class initializer.
|
||||
unsigned HasUninitializedFields : 1;
|
||||
|
||||
/// \brief True if there are any member using-declarations that inherit
|
||||
/// constructors from a base class.
|
||||
unsigned HasInheritedConstructor : 1;
|
||||
|
||||
/// \brief True if there are any member using-declarations named
|
||||
/// 'operator='.
|
||||
unsigned HasInheritedAssignment : 1;
|
||||
|
||||
/// \brief These flags are \c true if a defaulted corresponding special
|
||||
/// member can't be fully analyzed without performing overload resolution.
|
||||
/// @{
|
||||
bool NeedOverloadResolutionForMoveConstructor : 1;
|
||||
bool NeedOverloadResolutionForMoveAssignment : 1;
|
||||
bool NeedOverloadResolutionForDestructor : 1;
|
||||
unsigned NeedOverloadResolutionForMoveConstructor : 1;
|
||||
unsigned NeedOverloadResolutionForMoveAssignment : 1;
|
||||
unsigned NeedOverloadResolutionForDestructor : 1;
|
||||
/// @}
|
||||
|
||||
/// \brief These flags are \c true if an implicit defaulted corresponding
|
||||
/// special member would be defined as deleted.
|
||||
/// @{
|
||||
bool DefaultedMoveConstructorIsDeleted : 1;
|
||||
bool DefaultedMoveAssignmentIsDeleted : 1;
|
||||
bool DefaultedDestructorIsDeleted : 1;
|
||||
unsigned DefaultedMoveConstructorIsDeleted : 1;
|
||||
unsigned DefaultedMoveAssignmentIsDeleted : 1;
|
||||
unsigned DefaultedDestructorIsDeleted : 1;
|
||||
/// @}
|
||||
|
||||
/// \brief The trivial special members which this class has, per
|
||||
|
|
@ -411,33 +401,37 @@ class CXXRecordDecl : public RecordDecl {
|
|||
unsigned DeclaredNonTrivialSpecialMembers : 6;
|
||||
|
||||
/// \brief True when this class has a destructor with no semantic effect.
|
||||
bool HasIrrelevantDestructor : 1;
|
||||
unsigned HasIrrelevantDestructor : 1;
|
||||
|
||||
/// \brief True when this class has at least one user-declared constexpr
|
||||
/// constructor which is neither the copy nor move constructor.
|
||||
bool HasConstexprNonCopyMoveConstructor : 1;
|
||||
unsigned HasConstexprNonCopyMoveConstructor : 1;
|
||||
|
||||
/// \brief True if this class has a (possibly implicit) defaulted default
|
||||
/// constructor.
|
||||
unsigned HasDefaultedDefaultConstructor : 1;
|
||||
|
||||
/// \brief True if a defaulted default constructor for this class would
|
||||
/// be constexpr.
|
||||
bool DefaultedDefaultConstructorIsConstexpr : 1;
|
||||
unsigned DefaultedDefaultConstructorIsConstexpr : 1;
|
||||
|
||||
/// \brief True if this class has a constexpr default constructor.
|
||||
///
|
||||
/// This is true for either a user-declared constexpr default constructor
|
||||
/// or an implicitly declared constexpr default constructor.
|
||||
bool HasConstexprDefaultConstructor : 1;
|
||||
unsigned HasConstexprDefaultConstructor : 1;
|
||||
|
||||
/// \brief True when this class contains at least one non-static data
|
||||
/// member or base class of non-literal or volatile type.
|
||||
bool HasNonLiteralTypeFieldsOrBases : 1;
|
||||
unsigned HasNonLiteralTypeFieldsOrBases : 1;
|
||||
|
||||
/// \brief True when visible conversion functions are already computed
|
||||
/// and are available.
|
||||
bool ComputedVisibleConversions : 1;
|
||||
unsigned ComputedVisibleConversions : 1;
|
||||
|
||||
/// \brief Whether we have a C++11 user-provided default constructor (not
|
||||
/// explicitly deleted or defaulted).
|
||||
bool UserProvidedDefaultConstructor : 1;
|
||||
unsigned UserProvidedDefaultConstructor : 1;
|
||||
|
||||
/// \brief The special members which have been declared for this class,
|
||||
/// either by the user or implicitly.
|
||||
|
|
@ -445,25 +439,25 @@ class CXXRecordDecl : public RecordDecl {
|
|||
|
||||
/// \brief Whether an implicit copy constructor would have a const-qualified
|
||||
/// parameter.
|
||||
bool ImplicitCopyConstructorHasConstParam : 1;
|
||||
unsigned ImplicitCopyConstructorHasConstParam : 1;
|
||||
|
||||
/// \brief Whether an implicit copy assignment operator would have a
|
||||
/// const-qualified parameter.
|
||||
bool ImplicitCopyAssignmentHasConstParam : 1;
|
||||
unsigned ImplicitCopyAssignmentHasConstParam : 1;
|
||||
|
||||
/// \brief Whether any declared copy constructor has a const-qualified
|
||||
/// parameter.
|
||||
bool HasDeclaredCopyConstructorWithConstParam : 1;
|
||||
unsigned HasDeclaredCopyConstructorWithConstParam : 1;
|
||||
|
||||
/// \brief Whether any declared copy assignment operator has either a
|
||||
/// const-qualified reference parameter or a non-reference parameter.
|
||||
bool HasDeclaredCopyAssignmentWithConstParam : 1;
|
||||
unsigned HasDeclaredCopyAssignmentWithConstParam : 1;
|
||||
|
||||
/// \brief Whether this class describes a C++ lambda.
|
||||
bool IsLambda : 1;
|
||||
unsigned IsLambda : 1;
|
||||
|
||||
/// \brief Whether we are currently parsing base specifiers.
|
||||
bool IsParsingBaseSpecifiers : 1;
|
||||
unsigned IsParsingBaseSpecifiers : 1;
|
||||
|
||||
/// \brief The number of base class specifiers in Bases.
|
||||
unsigned NumBases;
|
||||
|
|
@ -515,16 +509,19 @@ class CXXRecordDecl : public RecordDecl {
|
|||
return getVBasesSlowCase();
|
||||
}
|
||||
|
||||
ArrayRef<CXXBaseSpecifier> bases() const {
|
||||
return llvm::makeArrayRef(getBases(), NumBases);
|
||||
}
|
||||
ArrayRef<CXXBaseSpecifier> vbases() const {
|
||||
return llvm::makeArrayRef(getVBases(), NumVBases);
|
||||
}
|
||||
|
||||
private:
|
||||
CXXBaseSpecifier *getBasesSlowCase() const;
|
||||
CXXBaseSpecifier *getVBasesSlowCase() const;
|
||||
};
|
||||
|
||||
typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
|
||||
DefinitionDataPtr;
|
||||
friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
|
||||
|
||||
mutable DefinitionDataPtr DefinitionData;
|
||||
struct DefinitionData *DefinitionData;
|
||||
|
||||
/// \brief Describes a C++ closure type (generated by a lambda expression).
|
||||
struct LambdaDefinitionData : public DefinitionData {
|
||||
|
|
@ -587,8 +584,14 @@ class CXXRecordDecl : public RecordDecl {
|
|||
|
||||
};
|
||||
|
||||
struct DefinitionData *dataPtr() const {
|
||||
// Complete the redecl chain (if necessary).
|
||||
getMostRecentDecl();
|
||||
return DefinitionData;
|
||||
}
|
||||
|
||||
struct DefinitionData &data() const {
|
||||
auto *DD = DefinitionData.get();
|
||||
auto *DD = dataPtr();
|
||||
assert(DD && "queried property of class with no definition");
|
||||
return *DD;
|
||||
}
|
||||
|
|
@ -596,7 +599,7 @@ class CXXRecordDecl : public RecordDecl {
|
|||
struct LambdaDefinitionData &getLambdaData() const {
|
||||
// No update required: a merged definition cannot change any lambda
|
||||
// properties.
|
||||
auto *DD = DefinitionData.getNotUpdated();
|
||||
auto *DD = DefinitionData;
|
||||
assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
|
||||
return static_cast<LambdaDefinitionData&>(*DD);
|
||||
}
|
||||
|
|
@ -673,11 +676,13 @@ public:
|
|||
}
|
||||
|
||||
CXXRecordDecl *getDefinition() const {
|
||||
auto *DD = DefinitionData.get();
|
||||
// We only need an update if we don't already know which
|
||||
// declaration is the definition.
|
||||
auto *DD = DefinitionData ? DefinitionData : dataPtr();
|
||||
return DD ? DD->Definition : nullptr;
|
||||
}
|
||||
|
||||
bool hasDefinition() const { return DefinitionData.get(); }
|
||||
bool hasDefinition() const { return DefinitionData || dataPtr(); }
|
||||
|
||||
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
|
|
@ -1021,7 +1026,7 @@ public:
|
|||
/// \brief Determine whether this class describes a lambda function object.
|
||||
bool isLambda() const {
|
||||
// An update record can't turn a non-lambda into a lambda.
|
||||
auto *DD = DefinitionData.getNotUpdated();
|
||||
auto *DD = DefinitionData;
|
||||
return DD && DD->IsLambda;
|
||||
}
|
||||
|
||||
|
|
@ -1136,9 +1141,10 @@ public:
|
|||
/// \brief Determine whether this is an empty class in the sense of
|
||||
/// (C++11 [meta.unary.prop]).
|
||||
///
|
||||
/// A non-union class is empty iff it has a virtual function, virtual base,
|
||||
/// data member (other than 0-width bit-field) or inherits from a non-empty
|
||||
/// class.
|
||||
/// The CXXRecordDecl is a class type, but not a union type,
|
||||
/// with no non-static data members other than bit-fields of length 0,
|
||||
/// no virtual member functions, no virtual base classes,
|
||||
/// and no base class B for which is_empty<B>::value is false.
|
||||
///
|
||||
/// \note This does NOT include a check for union-ness.
|
||||
bool isEmpty() const { return data().Empty; }
|
||||
|
|
@ -1270,6 +1276,14 @@ public:
|
|||
return !(data().HasTrivialSpecialMembers & SMF_Destructor);
|
||||
}
|
||||
|
||||
/// \brief Determine whether declaring a const variable with this type is ok
|
||||
/// per core issue 253.
|
||||
bool allowConstDefaultInit() const {
|
||||
return !data().HasUninitializedFields ||
|
||||
!(data().HasDefaultedDefaultConstructor ||
|
||||
needsImplicitDefaultConstructor());
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a destructor which has no
|
||||
/// semantic effect.
|
||||
///
|
||||
|
|
@ -1285,6 +1299,18 @@ public:
|
|||
return data().HasNonLiteralTypeFieldsOrBases;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a using-declaration that names
|
||||
/// a user-declared base class constructor.
|
||||
bool hasInheritedConstructor() const {
|
||||
return data().HasInheritedConstructor;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a using-declaration that names
|
||||
/// a base class assignment operator.
|
||||
bool hasInheritedAssignment() const {
|
||||
return data().HasInheritedAssignment;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class is considered trivially copyable per
|
||||
/// (C++11 [class]p6).
|
||||
bool isTriviallyCopyable() const;
|
||||
|
|
@ -1554,6 +1580,14 @@ public:
|
|||
static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path, DeclarationName Name);
|
||||
|
||||
/// \brief Base-class lookup callback that determines whether there exists
|
||||
/// an OpenMP declare reduction member with the given name.
|
||||
///
|
||||
/// This callback can be used with \c lookupInBases() to find members
|
||||
/// of the given name within a C++ class hierarchy.
|
||||
static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path, DeclarationName Name);
|
||||
|
||||
/// \brief Base-class lookup callback that determines whether there exists
|
||||
/// a member with the given name that can be used in a nested-name-specifier.
|
||||
///
|
||||
|
|
@ -1690,6 +1724,7 @@ public:
|
|||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTRecordWriter;
|
||||
friend class ASTReader;
|
||||
friend class ASTWriter;
|
||||
};
|
||||
|
|
@ -1795,6 +1830,8 @@ public:
|
|||
method_iterator begin_overridden_methods() const;
|
||||
method_iterator end_overridden_methods() const;
|
||||
unsigned size_overridden_methods() const;
|
||||
typedef ASTContext::overridden_method_range overridden_method_range;
|
||||
overridden_method_range overridden_methods() const;
|
||||
|
||||
/// Returns the parent of this method declaration, which
|
||||
/// is the class in which this method is defined.
|
||||
|
|
@ -1910,15 +1947,15 @@ class CXXCtorInitializer final
|
|||
|
||||
/// \brief If the initializee is a type, whether that type makes this
|
||||
/// a delegating initialization.
|
||||
bool IsDelegating : 1;
|
||||
unsigned IsDelegating : 1;
|
||||
|
||||
/// \brief If the initializer is a base initializer, this keeps track
|
||||
/// of whether the base is virtual or not.
|
||||
bool IsVirtual : 1;
|
||||
unsigned IsVirtual : 1;
|
||||
|
||||
/// \brief Whether or not the initializer is explicitly written
|
||||
/// in the sources.
|
||||
bool IsWritten : 1;
|
||||
unsigned IsWritten : 1;
|
||||
|
||||
/// If IsWritten is true, then this number keeps track of the textual order
|
||||
/// of this initializer in the original sources, counting from 0; otherwise,
|
||||
|
|
@ -2109,8 +2146,7 @@ public:
|
|||
assert(I < getNumArrayIndices() && "Out of bounds member array index");
|
||||
getTrailingObjects<VarDecl *>()[I] = Index;
|
||||
}
|
||||
ArrayRef<VarDecl *> getArrayIndexes() {
|
||||
assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
|
||||
ArrayRef<VarDecl *> getArrayIndices() {
|
||||
return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
|
||||
getNumArrayIndices());
|
||||
}
|
||||
|
|
@ -2121,6 +2157,23 @@ public:
|
|||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
/// Description of a constructor that was inherited from a base class.
|
||||
class InheritedConstructor {
|
||||
ConstructorUsingShadowDecl *Shadow;
|
||||
CXXConstructorDecl *BaseCtor;
|
||||
|
||||
public:
|
||||
InheritedConstructor() : Shadow(), BaseCtor() {}
|
||||
InheritedConstructor(ConstructorUsingShadowDecl *Shadow,
|
||||
CXXConstructorDecl *BaseCtor)
|
||||
: Shadow(Shadow), BaseCtor(BaseCtor) {}
|
||||
|
||||
explicit operator bool() const { return Shadow; }
|
||||
|
||||
ConstructorUsingShadowDecl *getShadowDecl() const { return Shadow; }
|
||||
CXXConstructorDecl *getConstructor() const { return BaseCtor; }
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ constructor within a class.
|
||||
///
|
||||
/// For example:
|
||||
|
|
@ -2131,40 +2184,51 @@ public:
|
|||
/// explicit X(int); // represented by a CXXConstructorDecl.
|
||||
/// };
|
||||
/// \endcode
|
||||
class CXXConstructorDecl : public CXXMethodDecl {
|
||||
class CXXConstructorDecl final
|
||||
: public CXXMethodDecl,
|
||||
private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
|
||||
void anchor() override;
|
||||
/// \brief Whether this constructor declaration has the \c explicit keyword
|
||||
/// specified.
|
||||
bool IsExplicitSpecified : 1;
|
||||
|
||||
/// \name Support for base and member initializers.
|
||||
/// \{
|
||||
/// \brief The arguments used to initialize the base or member.
|
||||
LazyCXXCtorInitializersPtr CtorInitializers;
|
||||
unsigned NumCtorInitializers;
|
||||
unsigned NumCtorInitializers : 30;
|
||||
/// \}
|
||||
|
||||
/// \brief Whether this constructor declaration has the \c explicit keyword
|
||||
/// specified.
|
||||
unsigned IsExplicitSpecified : 1;
|
||||
|
||||
/// \brief Whether this constructor declaration is an implicitly-declared
|
||||
/// inheriting constructor.
|
||||
unsigned IsInheritingConstructor : 1;
|
||||
|
||||
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
bool isExplicitSpecified, bool isInline,
|
||||
bool isImplicitlyDeclared, bool isConstexpr)
|
||||
bool isImplicitlyDeclared, bool isConstexpr,
|
||||
InheritedConstructor Inherited)
|
||||
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, isInline, isConstexpr, SourceLocation()),
|
||||
IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
|
||||
NumCtorInitializers(0) {
|
||||
CtorInitializers(nullptr), NumCtorInitializers(0),
|
||||
IsExplicitSpecified(isExplicitSpecified),
|
||||
IsInheritingConstructor((bool)Inherited) {
|
||||
setImplicit(isImplicitlyDeclared);
|
||||
if (Inherited)
|
||||
*getTrailingObjects<InheritedConstructor>() = Inherited;
|
||||
}
|
||||
|
||||
public:
|
||||
static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
|
||||
SourceLocation StartLoc,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
bool isExplicit,
|
||||
bool isInline, bool isImplicitlyDeclared,
|
||||
bool isConstexpr);
|
||||
static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID,
|
||||
bool InheritsConstructor);
|
||||
static CXXConstructorDecl *
|
||||
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||
bool isExplicit, bool isInline, bool isImplicitlyDeclared,
|
||||
bool isConstexpr,
|
||||
InheritedConstructor Inherited = InheritedConstructor());
|
||||
|
||||
/// \brief Determine whether this constructor declaration has the
|
||||
/// \c explicit keyword specified.
|
||||
|
|
@ -2311,11 +2375,15 @@ public:
|
|||
/// an object.
|
||||
bool isSpecializationCopyingObject() const;
|
||||
|
||||
/// \brief Get the constructor that this inheriting constructor is based on.
|
||||
const CXXConstructorDecl *getInheritedConstructor() const;
|
||||
/// \brief Determine whether this is an implicit constructor synthesized to
|
||||
/// model a call to a constructor inherited from a base class.
|
||||
bool isInheritingConstructor() const { return IsInheritingConstructor; }
|
||||
|
||||
/// \brief Set the constructor that this inheriting constructor is based on.
|
||||
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
|
||||
/// \brief Get the constructor that this inheriting constructor is based on.
|
||||
InheritedConstructor getInheritedConstructor() const {
|
||||
return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>()
|
||||
: InheritedConstructor();
|
||||
}
|
||||
|
||||
CXXConstructorDecl *getCanonicalDecl() override {
|
||||
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
|
||||
|
|
@ -2330,6 +2398,7 @@ public:
|
|||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ destructor within a class.
|
||||
|
|
@ -2774,18 +2843,6 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
|
|||
NamedDecl *UsingOrNextShadow;
|
||||
friend class UsingDecl;
|
||||
|
||||
UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
|
||||
UsingDecl *Using, NamedDecl *Target)
|
||||
: NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
|
||||
redeclarable_base(C), Underlying(Target),
|
||||
UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
|
||||
if (Target) {
|
||||
setDeclName(Target->getDeclName());
|
||||
IdentifierNamespace = Target->getIdentifierNamespace();
|
||||
}
|
||||
setImplicit();
|
||||
}
|
||||
|
||||
typedef Redeclarable<UsingShadowDecl> redeclarable_base;
|
||||
UsingShadowDecl *getNextRedeclarationImpl() override {
|
||||
return getNextRedeclaration();
|
||||
|
|
@ -2797,11 +2854,16 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
|
|||
return getMostRecentDecl();
|
||||
}
|
||||
|
||||
protected:
|
||||
UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, SourceLocation Loc,
|
||||
UsingDecl *Using, NamedDecl *Target);
|
||||
UsingShadowDecl(Kind K, ASTContext &C, EmptyShell);
|
||||
|
||||
public:
|
||||
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation Loc, UsingDecl *Using,
|
||||
NamedDecl *Target) {
|
||||
return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
|
||||
return new (C, DC) UsingShadowDecl(UsingShadow, C, DC, Loc, Using, Target);
|
||||
}
|
||||
|
||||
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
|
@ -2813,6 +2875,7 @@ public:
|
|||
using redeclarable_base::redecls;
|
||||
using redeclarable_base::getPreviousDecl;
|
||||
using redeclarable_base::getMostRecentDecl;
|
||||
using redeclarable_base::isFirstDecl;
|
||||
|
||||
UsingShadowDecl *getCanonicalDecl() override {
|
||||
return getFirstDecl();
|
||||
|
|
@ -2843,7 +2906,125 @@ public:
|
|||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
|
||||
static bool classofKind(Kind K) {
|
||||
return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow;
|
||||
}
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
};
|
||||
|
||||
/// \brief Represents a shadow constructor declaration introduced into a
|
||||
/// class by a C++11 using-declaration that names a constructor.
|
||||
///
|
||||
/// For example:
|
||||
/// \code
|
||||
/// struct Base { Base(int); };
|
||||
/// struct Derived {
|
||||
/// using Base::Base; // creates a UsingDecl and a ConstructorUsingShadowDecl
|
||||
/// };
|
||||
/// \endcode
|
||||
class ConstructorUsingShadowDecl final : public UsingShadowDecl {
|
||||
void anchor() override;
|
||||
|
||||
/// \brief If this constructor using declaration inherted the constructor
|
||||
/// from an indirect base class, this is the ConstructorUsingShadowDecl
|
||||
/// in the named direct base class from which the declaration was inherited.
|
||||
ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl;
|
||||
|
||||
/// \brief If this constructor using declaration inherted the constructor
|
||||
/// from an indirect base class, this is the ConstructorUsingShadowDecl
|
||||
/// that will be used to construct the unique direct or virtual base class
|
||||
/// that receives the constructor arguments.
|
||||
ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl;
|
||||
|
||||
/// \brief \c true if the constructor ultimately named by this using shadow
|
||||
/// declaration is within a virtual base class subobject of the class that
|
||||
/// contains this declaration.
|
||||
unsigned IsVirtual : 1;
|
||||
|
||||
ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
|
||||
UsingDecl *Using, NamedDecl *Target,
|
||||
bool TargetInVirtualBase)
|
||||
: UsingShadowDecl(ConstructorUsingShadow, C, DC, Loc, Using,
|
||||
Target->getUnderlyingDecl()),
|
||||
NominatedBaseClassShadowDecl(
|
||||
dyn_cast<ConstructorUsingShadowDecl>(Target)),
|
||||
ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl),
|
||||
IsVirtual(TargetInVirtualBase) {
|
||||
// If we found a constructor for a non-virtual base class, but it chains to
|
||||
// a constructor for a virtual base, we should directly call the virtual
|
||||
// base constructor instead.
|
||||
// FIXME: This logic belongs in Sema.
|
||||
if (!TargetInVirtualBase && NominatedBaseClassShadowDecl &&
|
||||
NominatedBaseClassShadowDecl->constructsVirtualBase()) {
|
||||
ConstructedBaseClassShadowDecl =
|
||||
NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl;
|
||||
IsVirtual = true;
|
||||
}
|
||||
}
|
||||
ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty)
|
||||
: UsingShadowDecl(ConstructorUsingShadow, C, Empty) {}
|
||||
|
||||
public:
|
||||
static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation Loc,
|
||||
UsingDecl *Using, NamedDecl *Target,
|
||||
bool IsVirtual);
|
||||
static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
||||
/// Returns the parent of this using shadow declaration, which
|
||||
/// is the class in which this is declared.
|
||||
//@{
|
||||
const CXXRecordDecl *getParent() const {
|
||||
return cast<CXXRecordDecl>(getDeclContext());
|
||||
}
|
||||
CXXRecordDecl *getParent() {
|
||||
return cast<CXXRecordDecl>(getDeclContext());
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \brief Get the inheriting constructor declaration for the direct base
|
||||
/// class from which this using shadow declaration was inherited, if there is
|
||||
/// one. This can be different for each redeclaration of the same shadow decl.
|
||||
ConstructorUsingShadowDecl *getNominatedBaseClassShadowDecl() const {
|
||||
return NominatedBaseClassShadowDecl;
|
||||
}
|
||||
|
||||
/// \brief Get the inheriting constructor declaration for the base class
|
||||
/// for which we don't have an explicit initializer, if there is one.
|
||||
ConstructorUsingShadowDecl *getConstructedBaseClassShadowDecl() const {
|
||||
return ConstructedBaseClassShadowDecl;
|
||||
}
|
||||
|
||||
/// \brief Get the base class that was named in the using declaration. This
|
||||
/// can be different for each redeclaration of this same shadow decl.
|
||||
CXXRecordDecl *getNominatedBaseClass() const;
|
||||
|
||||
/// \brief Get the base class whose constructor or constructor shadow
|
||||
/// declaration is passed the constructor arguments.
|
||||
CXXRecordDecl *getConstructedBaseClass() const {
|
||||
return cast<CXXRecordDecl>((ConstructedBaseClassShadowDecl
|
||||
? ConstructedBaseClassShadowDecl
|
||||
: getTargetDecl())
|
||||
->getDeclContext());
|
||||
}
|
||||
|
||||
/// \brief Returns \c true if the constructed base class is a virtual base
|
||||
/// class subobject of this declaration's class.
|
||||
bool constructsVirtualBase() const {
|
||||
return IsVirtual;
|
||||
}
|
||||
|
||||
/// \brief Get the constructor or constructor template in the derived class
|
||||
/// correspnding to this using shadow declaration, if it has been implicitly
|
||||
/// declared already.
|
||||
CXXConstructorDecl *getConstructor() const;
|
||||
void setConstructor(NamedDecl *Ctor);
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ConstructorUsingShadow; }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ private:
|
|||
/// True if this 'friend' declaration is unsupported. Eventually we
|
||||
/// will support every possible friend declaration, but for now we
|
||||
/// silently ignore some and set this flag to authorize all access.
|
||||
bool UnsupportedFriend : 1;
|
||||
unsigned UnsupportedFriend : 1;
|
||||
|
||||
// The number of "outer" template parameter lists in non-templatic
|
||||
// (currently unsupported) friend type declarations, such as
|
||||
|
|
|
|||
|
|
@ -351,11 +351,6 @@ public:
|
|||
typedef llvm::iterator_range<param_iterator> param_range;
|
||||
typedef llvm::iterator_range<param_const_iterator> param_const_range;
|
||||
|
||||
param_range params() { return param_range(param_begin(), param_end()); }
|
||||
param_const_range params() const {
|
||||
return param_const_range(param_begin(), param_end());
|
||||
}
|
||||
|
||||
param_const_iterator param_begin() const {
|
||||
return param_const_iterator(getParams());
|
||||
}
|
||||
|
|
@ -689,6 +684,216 @@ public:
|
|||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
enum class ObjCPropertyQueryKind : uint8_t {
|
||||
OBJC_PR_query_unknown = 0x00,
|
||||
OBJC_PR_query_instance,
|
||||
OBJC_PR_query_class
|
||||
};
|
||||
|
||||
/// \brief Represents one property declaration in an Objective-C interface.
|
||||
///
|
||||
/// For example:
|
||||
/// \code{.mm}
|
||||
/// \@property (assign, readwrite) int MyProperty;
|
||||
/// \endcode
|
||||
class ObjCPropertyDecl : public NamedDecl {
|
||||
void anchor() override;
|
||||
public:
|
||||
enum PropertyAttributeKind {
|
||||
OBJC_PR_noattr = 0x00,
|
||||
OBJC_PR_readonly = 0x01,
|
||||
OBJC_PR_getter = 0x02,
|
||||
OBJC_PR_assign = 0x04,
|
||||
OBJC_PR_readwrite = 0x08,
|
||||
OBJC_PR_retain = 0x10,
|
||||
OBJC_PR_copy = 0x20,
|
||||
OBJC_PR_nonatomic = 0x40,
|
||||
OBJC_PR_setter = 0x80,
|
||||
OBJC_PR_atomic = 0x100,
|
||||
OBJC_PR_weak = 0x200,
|
||||
OBJC_PR_strong = 0x400,
|
||||
OBJC_PR_unsafe_unretained = 0x800,
|
||||
/// Indicates that the nullability of the type was spelled with a
|
||||
/// property attribute rather than a type qualifier.
|
||||
OBJC_PR_nullability = 0x1000,
|
||||
OBJC_PR_null_resettable = 0x2000,
|
||||
OBJC_PR_class = 0x4000
|
||||
// Adding a property should change NumPropertyAttrsBits
|
||||
};
|
||||
|
||||
enum {
|
||||
/// \brief Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 15
|
||||
};
|
||||
|
||||
enum SetterKind { Assign, Retain, Copy, Weak };
|
||||
enum PropertyControl { None, Required, Optional };
|
||||
private:
|
||||
SourceLocation AtLoc; // location of \@property
|
||||
SourceLocation LParenLoc; // location of '(' starting attribute list or null.
|
||||
QualType DeclType;
|
||||
TypeSourceInfo *DeclTypeSourceInfo;
|
||||
unsigned PropertyAttributes : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
|
||||
// \@required/\@optional
|
||||
unsigned PropertyImplementation : 2;
|
||||
|
||||
Selector GetterName; // getter name of NULL if no getter
|
||||
Selector SetterName; // setter name of NULL if no setter
|
||||
|
||||
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
|
||||
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
|
||||
ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
|
||||
|
||||
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
||||
SourceLocation AtLocation, SourceLocation LParenLocation,
|
||||
QualType T, TypeSourceInfo *TSI,
|
||||
PropertyControl propControl)
|
||||
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
|
||||
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
|
||||
PropertyAttributes(OBJC_PR_noattr),
|
||||
PropertyAttributesAsWritten(OBJC_PR_noattr),
|
||||
PropertyImplementation(propControl),
|
||||
GetterName(Selector()),
|
||||
SetterName(Selector()),
|
||||
GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
|
||||
PropertyIvarDecl(nullptr) {}
|
||||
|
||||
public:
|
||||
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, SourceLocation AtLocation,
|
||||
SourceLocation LParenLocation,
|
||||
QualType T,
|
||||
TypeSourceInfo *TSI,
|
||||
PropertyControl propControl = None);
|
||||
|
||||
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||
|
||||
TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
|
||||
|
||||
QualType getType() const { return DeclType; }
|
||||
|
||||
void setType(QualType T, TypeSourceInfo *TSI) {
|
||||
DeclType = T;
|
||||
DeclTypeSourceInfo = TSI;
|
||||
}
|
||||
|
||||
/// Retrieve the type when this property is used with a specific base object
|
||||
/// type.
|
||||
QualType getUsageType(QualType objectType) const;
|
||||
|
||||
PropertyAttributeKind getPropertyAttributes() const {
|
||||
return PropertyAttributeKind(PropertyAttributes);
|
||||
}
|
||||
void setPropertyAttributes(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributes |= PRVal;
|
||||
}
|
||||
void overwritePropertyAttributes(unsigned PRVal) {
|
||||
PropertyAttributes = PRVal;
|
||||
}
|
||||
|
||||
PropertyAttributeKind getPropertyAttributesAsWritten() const {
|
||||
return PropertyAttributeKind(PropertyAttributesAsWritten);
|
||||
}
|
||||
|
||||
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributesAsWritten = PRVal;
|
||||
}
|
||||
|
||||
// Helper methods for accessing attributes.
|
||||
|
||||
/// isReadOnly - Return true iff the property has a setter.
|
||||
bool isReadOnly() const {
|
||||
return (PropertyAttributes & OBJC_PR_readonly);
|
||||
}
|
||||
|
||||
/// isAtomic - Return true if the property is atomic.
|
||||
bool isAtomic() const {
|
||||
return (PropertyAttributes & OBJC_PR_atomic);
|
||||
}
|
||||
|
||||
/// isRetaining - Return true if the property retains its value.
|
||||
bool isRetaining() const {
|
||||
return (PropertyAttributes &
|
||||
(OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
|
||||
}
|
||||
|
||||
bool isInstanceProperty() const { return !isClassProperty(); }
|
||||
bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
|
||||
ObjCPropertyQueryKind getQueryKind() const {
|
||||
return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
|
||||
ObjCPropertyQueryKind::OBJC_PR_query_instance;
|
||||
}
|
||||
static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) {
|
||||
return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class :
|
||||
ObjCPropertyQueryKind::OBJC_PR_query_instance;
|
||||
}
|
||||
|
||||
/// getSetterKind - Return the method used for doing assignment in
|
||||
/// the property setter. This is only valid if the property has been
|
||||
/// defined to have a setter.
|
||||
SetterKind getSetterKind() const {
|
||||
if (PropertyAttributes & OBJC_PR_strong)
|
||||
return getType()->isBlockPointerType() ? Copy : Retain;
|
||||
if (PropertyAttributes & OBJC_PR_retain)
|
||||
return Retain;
|
||||
if (PropertyAttributes & OBJC_PR_copy)
|
||||
return Copy;
|
||||
if (PropertyAttributes & OBJC_PR_weak)
|
||||
return Weak;
|
||||
return Assign;
|
||||
}
|
||||
|
||||
Selector getGetterName() const { return GetterName; }
|
||||
void setGetterName(Selector Sel) { GetterName = Sel; }
|
||||
|
||||
Selector getSetterName() const { return SetterName; }
|
||||
void setSetterName(Selector Sel) { SetterName = Sel; }
|
||||
|
||||
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
|
||||
void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
|
||||
|
||||
ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
|
||||
void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
|
||||
|
||||
// Related to \@optional/\@required declared in \@protocol
|
||||
void setPropertyImplementation(PropertyControl pc) {
|
||||
PropertyImplementation = pc;
|
||||
}
|
||||
PropertyControl getPropertyImplementation() const {
|
||||
return PropertyControl(PropertyImplementation);
|
||||
}
|
||||
|
||||
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
|
||||
PropertyIvarDecl = Ivar;
|
||||
}
|
||||
ObjCIvarDecl *getPropertyIvarDecl() const {
|
||||
return PropertyIvarDecl;
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(AtLoc, getLocation());
|
||||
}
|
||||
|
||||
/// Get the default name of the synthesized ivar.
|
||||
IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
|
||||
|
||||
/// Lookup a property by name in the specified DeclContext.
|
||||
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
|
||||
const IdentifierInfo *propertyID,
|
||||
ObjCPropertyQueryKind queryKind);
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCProperty; }
|
||||
};
|
||||
|
||||
/// ObjCContainerDecl - Represents a container for method declarations.
|
||||
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
|
||||
/// ObjCProtocolDecl, and ObjCImplDecl.
|
||||
|
|
@ -708,7 +913,7 @@ public:
|
|||
SourceLocation atStartLoc)
|
||||
: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
|
||||
|
||||
// Iterator access to properties.
|
||||
// Iterator access to instance/class properties.
|
||||
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
|
||||
typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
|
||||
prop_range;
|
||||
|
|
@ -721,6 +926,36 @@ public:
|
|||
return prop_iterator(decls_end());
|
||||
}
|
||||
|
||||
typedef filtered_decl_iterator<ObjCPropertyDecl,
|
||||
&ObjCPropertyDecl::isInstanceProperty>
|
||||
instprop_iterator;
|
||||
typedef llvm::iterator_range<instprop_iterator> instprop_range;
|
||||
|
||||
instprop_range instance_properties() const {
|
||||
return instprop_range(instprop_begin(), instprop_end());
|
||||
}
|
||||
instprop_iterator instprop_begin() const {
|
||||
return instprop_iterator(decls_begin());
|
||||
}
|
||||
instprop_iterator instprop_end() const {
|
||||
return instprop_iterator(decls_end());
|
||||
}
|
||||
|
||||
typedef filtered_decl_iterator<ObjCPropertyDecl,
|
||||
&ObjCPropertyDecl::isClassProperty>
|
||||
classprop_iterator;
|
||||
typedef llvm::iterator_range<classprop_iterator> classprop_range;
|
||||
|
||||
classprop_range class_properties() const {
|
||||
return classprop_range(classprop_begin(), classprop_end());
|
||||
}
|
||||
classprop_iterator classprop_begin() const {
|
||||
return classprop_iterator(decls_begin());
|
||||
}
|
||||
classprop_iterator classprop_end() const {
|
||||
return classprop_iterator(decls_end());
|
||||
}
|
||||
|
||||
// Iterator access to instance/class methods.
|
||||
typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
|
||||
typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
|
||||
|
|
@ -780,9 +1015,12 @@ public:
|
|||
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
|
||||
|
||||
ObjCPropertyDecl *
|
||||
FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
|
||||
FindPropertyDeclaration(const IdentifierInfo *PropertyId,
|
||||
ObjCPropertyQueryKind QueryKind) const;
|
||||
|
||||
typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
|
||||
typedef llvm::DenseMap<std::pair<IdentifierInfo*,
|
||||
unsigned/*isClassProperty*/>,
|
||||
ObjCPropertyDecl*> PropertyMap;
|
||||
|
||||
typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
|
||||
ProtocolPropertyMap;
|
||||
|
|
@ -886,15 +1124,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
|||
|
||||
/// \brief Indicates that the contents of this Objective-C class will be
|
||||
/// completed by the external AST source when required.
|
||||
mutable bool ExternallyCompleted : 1;
|
||||
mutable unsigned ExternallyCompleted : 1;
|
||||
|
||||
/// \brief Indicates that the ivar cache does not yet include ivars
|
||||
/// declared in the implementation.
|
||||
mutable bool IvarListMissingImplementation : 1;
|
||||
mutable unsigned IvarListMissingImplementation : 1;
|
||||
|
||||
/// Indicates that this interface decl contains at least one initializer
|
||||
/// marked with the 'objc_designated_initializer' attribute.
|
||||
bool HasDesignatedInitializers : 1;
|
||||
unsigned HasDesignatedInitializers : 1;
|
||||
|
||||
enum InheritedDesignatedInitializersState {
|
||||
/// We didn't calculate whether the designated initializers should be
|
||||
|
|
@ -1463,7 +1701,8 @@ public:
|
|||
}
|
||||
|
||||
ObjCPropertyDecl
|
||||
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
|
||||
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId,
|
||||
ObjCPropertyQueryKind QueryKind) const;
|
||||
|
||||
void collectPropertiesToImplement(PropertyMap &PM,
|
||||
PropertyDeclOrder &PO) const override;
|
||||
|
|
@ -1529,8 +1768,9 @@ public:
|
|||
/// including in all categories except for category passed
|
||||
/// as argument.
|
||||
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
|
||||
const ObjCCategoryDecl *Cat) const {
|
||||
return lookupMethod(Sel, true/*isInstance*/,
|
||||
const ObjCCategoryDecl *Cat,
|
||||
bool IsClassProperty) const {
|
||||
return lookupMethod(Sel, !IsClassProperty/*isInstance*/,
|
||||
false/*shallowCategoryLookup*/,
|
||||
true /* followsSuper */,
|
||||
Cat);
|
||||
|
|
@ -2099,7 +2339,8 @@ public:
|
|||
|
||||
void addPropertyImplementation(ObjCPropertyImplDecl *property);
|
||||
|
||||
ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
|
||||
ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId,
|
||||
ObjCPropertyQueryKind queryKind) const;
|
||||
ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
|
||||
|
||||
// Iterator access to properties.
|
||||
|
|
@ -2407,197 +2648,6 @@ public:
|
|||
|
||||
};
|
||||
|
||||
/// \brief Represents one property declaration in an Objective-C interface.
|
||||
///
|
||||
/// For example:
|
||||
/// \code{.mm}
|
||||
/// \@property (assign, readwrite) int MyProperty;
|
||||
/// \endcode
|
||||
class ObjCPropertyDecl : public NamedDecl {
|
||||
void anchor() override;
|
||||
public:
|
||||
enum PropertyAttributeKind {
|
||||
OBJC_PR_noattr = 0x00,
|
||||
OBJC_PR_readonly = 0x01,
|
||||
OBJC_PR_getter = 0x02,
|
||||
OBJC_PR_assign = 0x04,
|
||||
OBJC_PR_readwrite = 0x08,
|
||||
OBJC_PR_retain = 0x10,
|
||||
OBJC_PR_copy = 0x20,
|
||||
OBJC_PR_nonatomic = 0x40,
|
||||
OBJC_PR_setter = 0x80,
|
||||
OBJC_PR_atomic = 0x100,
|
||||
OBJC_PR_weak = 0x200,
|
||||
OBJC_PR_strong = 0x400,
|
||||
OBJC_PR_unsafe_unretained = 0x800,
|
||||
/// Indicates that the nullability of the type was spelled with a
|
||||
/// property attribute rather than a type qualifier.
|
||||
OBJC_PR_nullability = 0x1000,
|
||||
OBJC_PR_null_resettable = 0x2000
|
||||
// Adding a property should change NumPropertyAttrsBits
|
||||
};
|
||||
|
||||
enum {
|
||||
/// \brief Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 14
|
||||
};
|
||||
|
||||
enum SetterKind { Assign, Retain, Copy, Weak };
|
||||
enum PropertyControl { None, Required, Optional };
|
||||
private:
|
||||
SourceLocation AtLoc; // location of \@property
|
||||
SourceLocation LParenLoc; // location of '(' starting attribute list or null.
|
||||
QualType DeclType;
|
||||
TypeSourceInfo *DeclTypeSourceInfo;
|
||||
unsigned PropertyAttributes : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
|
||||
// \@required/\@optional
|
||||
unsigned PropertyImplementation : 2;
|
||||
|
||||
Selector GetterName; // getter name of NULL if no getter
|
||||
Selector SetterName; // setter name of NULL if no setter
|
||||
|
||||
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
|
||||
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
|
||||
ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
|
||||
|
||||
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
||||
SourceLocation AtLocation, SourceLocation LParenLocation,
|
||||
QualType T, TypeSourceInfo *TSI,
|
||||
PropertyControl propControl)
|
||||
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
|
||||
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
|
||||
PropertyAttributes(OBJC_PR_noattr),
|
||||
PropertyAttributesAsWritten(OBJC_PR_noattr),
|
||||
PropertyImplementation(propControl),
|
||||
GetterName(Selector()),
|
||||
SetterName(Selector()),
|
||||
GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
|
||||
PropertyIvarDecl(nullptr) {}
|
||||
|
||||
public:
|
||||
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, SourceLocation AtLocation,
|
||||
SourceLocation LParenLocation,
|
||||
QualType T,
|
||||
TypeSourceInfo *TSI,
|
||||
PropertyControl propControl = None);
|
||||
|
||||
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||
|
||||
TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
|
||||
|
||||
QualType getType() const { return DeclType; }
|
||||
|
||||
void setType(QualType T, TypeSourceInfo *TSI) {
|
||||
DeclType = T;
|
||||
DeclTypeSourceInfo = TSI;
|
||||
}
|
||||
|
||||
/// Retrieve the type when this property is used with a specific base object
|
||||
/// type.
|
||||
QualType getUsageType(QualType objectType) const;
|
||||
|
||||
PropertyAttributeKind getPropertyAttributes() const {
|
||||
return PropertyAttributeKind(PropertyAttributes);
|
||||
}
|
||||
void setPropertyAttributes(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributes |= PRVal;
|
||||
}
|
||||
void overwritePropertyAttributes(unsigned PRVal) {
|
||||
PropertyAttributes = PRVal;
|
||||
}
|
||||
|
||||
PropertyAttributeKind getPropertyAttributesAsWritten() const {
|
||||
return PropertyAttributeKind(PropertyAttributesAsWritten);
|
||||
}
|
||||
|
||||
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributesAsWritten = PRVal;
|
||||
}
|
||||
|
||||
// Helper methods for accessing attributes.
|
||||
|
||||
/// isReadOnly - Return true iff the property has a setter.
|
||||
bool isReadOnly() const {
|
||||
return (PropertyAttributes & OBJC_PR_readonly);
|
||||
}
|
||||
|
||||
/// isAtomic - Return true if the property is atomic.
|
||||
bool isAtomic() const {
|
||||
return (PropertyAttributes & OBJC_PR_atomic);
|
||||
}
|
||||
|
||||
/// isRetaining - Return true if the property retains its value.
|
||||
bool isRetaining() const {
|
||||
return (PropertyAttributes &
|
||||
(OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
|
||||
}
|
||||
|
||||
/// getSetterKind - Return the method used for doing assignment in
|
||||
/// the property setter. This is only valid if the property has been
|
||||
/// defined to have a setter.
|
||||
SetterKind getSetterKind() const {
|
||||
if (PropertyAttributes & OBJC_PR_strong)
|
||||
return getType()->isBlockPointerType() ? Copy : Retain;
|
||||
if (PropertyAttributes & OBJC_PR_retain)
|
||||
return Retain;
|
||||
if (PropertyAttributes & OBJC_PR_copy)
|
||||
return Copy;
|
||||
if (PropertyAttributes & OBJC_PR_weak)
|
||||
return Weak;
|
||||
return Assign;
|
||||
}
|
||||
|
||||
Selector getGetterName() const { return GetterName; }
|
||||
void setGetterName(Selector Sel) { GetterName = Sel; }
|
||||
|
||||
Selector getSetterName() const { return SetterName; }
|
||||
void setSetterName(Selector Sel) { SetterName = Sel; }
|
||||
|
||||
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
|
||||
void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
|
||||
|
||||
ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
|
||||
void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
|
||||
|
||||
// Related to \@optional/\@required declared in \@protocol
|
||||
void setPropertyImplementation(PropertyControl pc) {
|
||||
PropertyImplementation = pc;
|
||||
}
|
||||
PropertyControl getPropertyImplementation() const {
|
||||
return PropertyControl(PropertyImplementation);
|
||||
}
|
||||
|
||||
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
|
||||
PropertyIvarDecl = Ivar;
|
||||
}
|
||||
ObjCIvarDecl *getPropertyIvarDecl() const {
|
||||
return PropertyIvarDecl;
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(AtLoc, getLocation());
|
||||
}
|
||||
|
||||
/// Get the default name of the synthesized ivar.
|
||||
IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
|
||||
|
||||
/// Lookup a property by name in the specified DeclContext.
|
||||
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
|
||||
const IdentifierInfo *propertyID);
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCProperty; }
|
||||
};
|
||||
|
||||
/// ObjCPropertyImplDecl - Represents implementation declaration of a property
|
||||
/// in a class or category implementation block. For example:
|
||||
/// \@synthesize prop1 = ivar1;
|
||||
|
|
|
|||
|
|
@ -15,11 +15,14 @@
|
|||
#ifndef LLVM_CLANG_AST_DECLOPENMP_H
|
||||
#define LLVM_CLANG_AST_DECLOPENMP_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
|
||||
namespace clang {
|
||||
class Expr;
|
||||
|
||||
/// \brief This represents '#pragma omp threadprivate ...' directive.
|
||||
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
|
||||
|
|
@ -86,6 +89,107 @@ public:
|
|||
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
/// \brief This represents '#pragma omp declare reduction ...' directive.
|
||||
/// For example, in the following, declared reduction 'foo' for types 'int' and
|
||||
/// 'float':
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
|
||||
/// initializer (omp_priv = 0)
|
||||
/// \endcode
|
||||
///
|
||||
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
|
||||
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
|
||||
private:
|
||||
friend class ASTDeclReader;
|
||||
/// \brief Combiner for declare reduction construct.
|
||||
Expr *Combiner;
|
||||
/// \brief Initializer for declare reduction construct.
|
||||
Expr *Initializer;
|
||||
/// \brief Reference to the previous declare reduction construct in the same
|
||||
/// scope with the same name. Required for proper templates instantiation if
|
||||
/// the declare reduction construct is declared inside compound statement.
|
||||
LazyDeclPtr PrevDeclInScope;
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, QualType Ty,
|
||||
OMPDeclareReductionDecl *PrevDeclInScope)
|
||||
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
|
||||
Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {}
|
||||
|
||||
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
|
||||
PrevDeclInScope = Prev;
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Create declare reduction node.
|
||||
static OMPDeclareReductionDecl *
|
||||
Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
|
||||
/// \brief Create deserialized declare reduction node.
|
||||
static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
||||
/// \brief Get combiner expression of the declare reduction construct.
|
||||
Expr *getCombiner() { return Combiner; }
|
||||
const Expr *getCombiner() const { return Combiner; }
|
||||
/// \brief Set combiner expression for the declare reduction construct.
|
||||
void setCombiner(Expr *E) { Combiner = E; }
|
||||
|
||||
/// \brief Get initializer expression (if specified) of the declare reduction
|
||||
/// construct.
|
||||
Expr *getInitializer() { return Initializer; }
|
||||
const Expr *getInitializer() const { return Initializer; }
|
||||
/// \brief Set initializer expression for the declare reduction construct.
|
||||
void setInitializer(Expr *E) { Initializer = E; }
|
||||
|
||||
/// \brief Get reference to previous declare reduction construct in the same
|
||||
/// scope with the same name.
|
||||
OMPDeclareReductionDecl *getPrevDeclInScope();
|
||||
const OMPDeclareReductionDecl *getPrevDeclInScope() const;
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
|
||||
static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
|
||||
}
|
||||
static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<OMPDeclareReductionDecl *>(
|
||||
const_cast<DeclContext *>(DC));
|
||||
}
|
||||
};
|
||||
|
||||
/// Pseudo declaration for capturing expressions. Also is used for capturing of
|
||||
/// non-static data members in non-static member functions.
|
||||
///
|
||||
/// Clang supports capturing of variables only, but OpenMP 4.5 allows to
|
||||
/// privatize non-static members of current class in non-static member
|
||||
/// functions. This pseudo-declaration allows properly handle this kind of
|
||||
/// capture by wrapping captured expression into a variable-like declaration.
|
||||
class OMPCapturedExprDecl final : public VarDecl {
|
||||
friend class ASTDeclReader;
|
||||
void anchor() override;
|
||||
|
||||
OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
|
||||
QualType Type)
|
||||
: VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id,
|
||||
Type, nullptr, SC_None) {
|
||||
setImplicit();
|
||||
}
|
||||
|
||||
public:
|
||||
static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
IdentifierInfo *Id, QualType T);
|
||||
|
||||
static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
|
@ -183,7 +184,7 @@ class TemplateArgumentList final
|
|||
|
||||
// Constructs an instance with an internal Argument list, containing
|
||||
// a copy of the Args array. (Called by CreateCopy)
|
||||
TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs);
|
||||
TemplateArgumentList(ArrayRef<TemplateArgument> Args);
|
||||
|
||||
public:
|
||||
/// \brief Type used to indicate that the template argument list itself is a
|
||||
|
|
@ -193,16 +194,14 @@ public:
|
|||
/// \brief Create a new template argument list that copies the given set of
|
||||
/// template arguments.
|
||||
static TemplateArgumentList *CreateCopy(ASTContext &Context,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
ArrayRef<TemplateArgument> Args);
|
||||
|
||||
/// \brief Construct a new, temporary template argument list on the stack.
|
||||
///
|
||||
/// The template argument list does not own the template arguments
|
||||
/// provided.
|
||||
explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args,
|
||||
unsigned NumArgs)
|
||||
: Arguments(Args), NumArguments(NumArgs) {}
|
||||
explicit TemplateArgumentList(OnStackType, ArrayRef<TemplateArgument> Args)
|
||||
: Arguments(Args.data()), NumArguments(Args.size()) {}
|
||||
|
||||
/// \brief Produces a shallow copy of the given template argument list.
|
||||
///
|
||||
|
|
@ -332,24 +331,23 @@ class TemplateDecl : public NamedDecl {
|
|||
void anchor() override;
|
||||
protected:
|
||||
// This is probably never used.
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
|
||||
TemplateParams(nullptr) {}
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
|
||||
TemplateParams(nullptr) {}
|
||||
|
||||
// Construct a template decl with the given name and parameters.
|
||||
// Used when there is not templated element (tt-params).
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, TemplateParameterList *Params)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
|
||||
TemplateParams(Params) {}
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
|
||||
TemplateParams(Params) {}
|
||||
|
||||
// Construct a template decl with name, parameters, and templated element.
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, TemplateParameterList *Params,
|
||||
NamedDecl *Decl)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
|
||||
TemplateParams(Params) { }
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params, NamedDecl *Decl)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false),
|
||||
TemplateParams(Params) {}
|
||||
|
||||
public:
|
||||
/// Get the list of template parameters
|
||||
TemplateParameterList *getTemplateParameters() const {
|
||||
|
|
@ -357,7 +355,7 @@ public:
|
|||
}
|
||||
|
||||
/// Get the underlying, templated declaration.
|
||||
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
|
||||
NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
|
@ -367,20 +365,30 @@ public:
|
|||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(TemplateParams->getTemplateLoc(),
|
||||
TemplatedDecl->getSourceRange().getEnd());
|
||||
TemplatedDecl.getPointer()->getSourceRange().getEnd());
|
||||
}
|
||||
|
||||
/// Whether this is a (C++ Concepts TS) function or variable concept.
|
||||
bool isConcept() const { return TemplatedDecl.getInt(); }
|
||||
void setConcept() { TemplatedDecl.setInt(true); }
|
||||
|
||||
protected:
|
||||
NamedDecl *TemplatedDecl;
|
||||
/// \brief The named declaration from which this template was instantiated.
|
||||
/// (or null).
|
||||
///
|
||||
/// The boolean value will be true to indicate that this template
|
||||
/// (function or variable) is a concept.
|
||||
llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl;
|
||||
|
||||
TemplateParameterList* TemplateParams;
|
||||
|
||||
public:
|
||||
/// \brief Initialize the underlying templated declaration and
|
||||
/// template parameters.
|
||||
void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
|
||||
assert(!TemplatedDecl && "TemplatedDecl already set!");
|
||||
assert(!TemplatedDecl.getPointer() && "TemplatedDecl already set!");
|
||||
assert(!TemplateParams && "TemplateParams already set!");
|
||||
TemplatedDecl = templatedDecl;
|
||||
TemplatedDecl.setPointer(templatedDecl);
|
||||
TemplateParams = templateParams;
|
||||
}
|
||||
};
|
||||
|
|
@ -481,8 +489,8 @@ public:
|
|||
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
|
||||
ASTContext &Context) {
|
||||
ID.AddInteger(TemplateArgs.size());
|
||||
for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
|
||||
TemplateArgs[Arg].Profile(ID, Context);
|
||||
for (const TemplateArgument &TemplateArg : TemplateArgs)
|
||||
TemplateArg.Profile(ID, Context);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -889,7 +897,7 @@ public:
|
|||
|
||||
/// Get the underlying function declaration of the template.
|
||||
FunctionDecl *getTemplatedDecl() const {
|
||||
return static_cast<FunctionDecl*>(TemplatedDecl);
|
||||
return static_cast<FunctionDecl *>(TemplatedDecl.getPointer());
|
||||
}
|
||||
|
||||
/// Returns whether this template declaration defines the primary
|
||||
|
|
@ -1171,9 +1179,8 @@ class NonTypeTemplateParmDecl final
|
|||
SourceLocation IdLoc, unsigned D, unsigned P,
|
||||
IdentifierInfo *Id, QualType T,
|
||||
TypeSourceInfo *TInfo,
|
||||
const QualType *ExpandedTypes,
|
||||
unsigned NumExpandedTypes,
|
||||
TypeSourceInfo **ExpandedTInfos);
|
||||
ArrayRef<QualType> ExpandedTypes,
|
||||
ArrayRef<TypeSourceInfo *> ExpandedTInfos);
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend TrailingObjects;
|
||||
|
|
@ -1187,9 +1194,8 @@ public:
|
|||
static NonTypeTemplateParmDecl *
|
||||
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
const QualType *ExpandedTypes, unsigned NumExpandedTypes,
|
||||
TypeSourceInfo **ExpandedTInfos);
|
||||
QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
|
||||
ArrayRef<TypeSourceInfo *> ExpandedTInfos);
|
||||
|
||||
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
|
@ -1352,8 +1358,7 @@ class TemplateTemplateParmDecl final
|
|||
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
|
||||
unsigned D, unsigned P,
|
||||
IdentifierInfo *Id, TemplateParameterList *Params,
|
||||
unsigned NumExpansions,
|
||||
TemplateParameterList * const *Expansions);
|
||||
ArrayRef<TemplateParameterList *> Expansions);
|
||||
|
||||
public:
|
||||
static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
|
||||
|
|
@ -1480,8 +1485,8 @@ public:
|
|||
};
|
||||
|
||||
/// \brief Represents the builtin template declaration which is used to
|
||||
/// implement __make_integer_seq. It serves no real purpose beyond existing as
|
||||
/// a place to hold template parameters.
|
||||
/// implement __make_integer_seq and other builtin templates. It serves
|
||||
/// no real purpose beyond existing as a place to hold template parameters.
|
||||
class BuiltinTemplateDecl : public TemplateDecl {
|
||||
void anchor() override;
|
||||
|
||||
|
|
@ -1573,8 +1578,7 @@ protected:
|
|||
DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
ClassTemplateSpecializationDecl *PrevDecl);
|
||||
|
||||
explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
|
||||
|
|
@ -1584,8 +1588,7 @@ public:
|
|||
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
ClassTemplateSpecializationDecl *PrevDecl);
|
||||
static ClassTemplateSpecializationDecl *
|
||||
CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
|
@ -1762,8 +1765,8 @@ public:
|
|||
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
|
||||
ASTContext &Context) {
|
||||
ID.AddInteger(TemplateArgs.size());
|
||||
for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
|
||||
TemplateArgs[Arg].Profile(ID, Context);
|
||||
for (const TemplateArgument &TemplateArg : TemplateArgs)
|
||||
TemplateArg.Profile(ID, Context);
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
|
@ -1801,8 +1804,7 @@ class ClassTemplatePartialSpecializationDecl
|
|||
SourceLocation IdLoc,
|
||||
TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
const ASTTemplateArgumentListInfo *ArgsAsWritten,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl);
|
||||
|
||||
|
|
@ -1817,8 +1819,7 @@ public:
|
|||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos,
|
||||
QualType CanonInjectedType,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl);
|
||||
|
|
@ -1867,6 +1868,10 @@ public:
|
|||
cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
|
||||
return First->InstantiatedFromMember.getPointer();
|
||||
}
|
||||
ClassTemplatePartialSpecializationDecl *
|
||||
getInstantiatedFromMemberTemplate() const {
|
||||
return getInstantiatedFromMember();
|
||||
}
|
||||
|
||||
void setInstantiatedFromMember(
|
||||
ClassTemplatePartialSpecializationDecl *PartialSpec) {
|
||||
|
|
@ -1982,7 +1987,7 @@ public:
|
|||
|
||||
/// \brief Get the underlying class declarations of the template.
|
||||
CXXRecordDecl *getTemplatedDecl() const {
|
||||
return static_cast<CXXRecordDecl *>(TemplatedDecl);
|
||||
return static_cast<CXXRecordDecl *>(TemplatedDecl.getPointer());
|
||||
}
|
||||
|
||||
/// \brief Returns whether this template declaration defines the primary
|
||||
|
|
@ -2154,18 +2159,11 @@ private:
|
|||
// Location of the 'friend' specifier.
|
||||
SourceLocation FriendLoc;
|
||||
|
||||
|
||||
FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
|
||||
unsigned NParams,
|
||||
TemplateParameterList **Params,
|
||||
FriendUnion Friend,
|
||||
SourceLocation FriendLoc)
|
||||
: Decl(Decl::FriendTemplate, DC, Loc),
|
||||
NumParams(NParams),
|
||||
Params(Params),
|
||||
Friend(Friend),
|
||||
FriendLoc(FriendLoc)
|
||||
{}
|
||||
MutableArrayRef<TemplateParameterList *> Params,
|
||||
FriendUnion Friend, SourceLocation FriendLoc)
|
||||
: Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()),
|
||||
Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {}
|
||||
|
||||
FriendTemplateDecl(EmptyShell Empty)
|
||||
: Decl(Decl::FriendTemplate, Empty),
|
||||
|
|
@ -2174,12 +2172,10 @@ private:
|
|||
{}
|
||||
|
||||
public:
|
||||
static FriendTemplateDecl *Create(ASTContext &Context,
|
||||
DeclContext *DC, SourceLocation Loc,
|
||||
unsigned NParams,
|
||||
TemplateParameterList **Params,
|
||||
FriendUnion Friend,
|
||||
SourceLocation FriendLoc);
|
||||
static FriendTemplateDecl *
|
||||
Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
|
||||
MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend,
|
||||
SourceLocation FriendLoc);
|
||||
|
||||
static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
|
|
@ -2245,7 +2241,7 @@ protected:
|
|||
public:
|
||||
/// Get the underlying function declaration of the template.
|
||||
TypeAliasDecl *getTemplatedDecl() const {
|
||||
return static_cast<TypeAliasDecl*>(TemplatedDecl);
|
||||
return static_cast<TypeAliasDecl *>(TemplatedDecl.getPointer());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2319,9 +2315,9 @@ class ClassScopeFunctionSpecializationDecl : public Decl {
|
|||
ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
|
||||
CXXMethodDecl *FD, bool Args,
|
||||
TemplateArgumentListInfo TemplArgs)
|
||||
: Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
|
||||
Specialization(FD), HasExplicitTemplateArgs(Args),
|
||||
TemplateArgs(TemplArgs) {}
|
||||
: Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
|
||||
Specialization(FD), HasExplicitTemplateArgs(Args),
|
||||
TemplateArgs(std::move(TemplArgs)) {}
|
||||
|
||||
ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
|
||||
: Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
|
||||
|
|
@ -2342,7 +2338,7 @@ public:
|
|||
bool HasExplicitTemplateArgs,
|
||||
TemplateArgumentListInfo TemplateArgs) {
|
||||
return new (C, DC) ClassScopeFunctionSpecializationDecl(
|
||||
DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
|
||||
DC, Loc, FD, HasExplicitTemplateArgs, std::move(TemplateArgs));
|
||||
}
|
||||
|
||||
static ClassScopeFunctionSpecializationDecl *
|
||||
|
|
@ -2428,8 +2424,8 @@ protected:
|
|||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
VarTemplateDecl *SpecializedTemplate,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
StorageClass S, const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
StorageClass S,
|
||||
ArrayRef<TemplateArgument> Args);
|
||||
|
||||
explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
|
||||
|
||||
|
|
@ -2437,8 +2433,8 @@ public:
|
|||
static VarTemplateSpecializationDecl *
|
||||
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
|
||||
TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
TypeSourceInfo *TInfo, StorageClass S,
|
||||
ArrayRef<TemplateArgument> Args);
|
||||
static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
||||
|
|
@ -2502,17 +2498,11 @@ public:
|
|||
/// it was instantiated.
|
||||
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
|
||||
getInstantiatedFrom() const {
|
||||
if (getSpecializationKind() != TSK_ImplicitInstantiation &&
|
||||
getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
|
||||
getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
|
||||
if (!isTemplateInstantiation(getSpecializationKind()))
|
||||
return llvm::PointerUnion<VarTemplateDecl *,
|
||||
VarTemplatePartialSpecializationDecl *>();
|
||||
|
||||
if (SpecializedPartialSpecialization *PartialSpec =
|
||||
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
|
||||
return PartialSpec->PartialSpecialization;
|
||||
|
||||
return SpecializedTemplate.get<VarTemplateDecl *>();
|
||||
return getSpecializedTemplateOrPartial();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the variable template or variable template partial
|
||||
|
|
@ -2610,8 +2600,8 @@ public:
|
|||
ArrayRef<TemplateArgument> TemplateArgs,
|
||||
ASTContext &Context) {
|
||||
ID.AddInteger(TemplateArgs.size());
|
||||
for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
|
||||
TemplateArgs[Arg].Profile(ID, Context);
|
||||
for (const TemplateArgument &TemplateArg : TemplateArgs)
|
||||
TemplateArg.Profile(ID, Context);
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
|
@ -2647,7 +2637,7 @@ class VarTemplatePartialSpecializationDecl
|
|||
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
|
||||
StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const ASTTemplateArgumentListInfo *ArgInfos);
|
||||
|
||||
VarTemplatePartialSpecializationDecl(ASTContext &Context)
|
||||
|
|
@ -2660,8 +2650,8 @@ public:
|
|||
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T,
|
||||
TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
|
||||
unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
|
||||
TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos);
|
||||
|
||||
static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
|
@ -2808,7 +2798,7 @@ public:
|
|||
|
||||
/// \brief Get the underlying variable declarations of the template.
|
||||
VarDecl *getTemplatedDecl() const {
|
||||
return static_cast<VarDecl *>(TemplatedDecl);
|
||||
return static_cast<VarDecl *>(TemplatedDecl.getPointer());
|
||||
}
|
||||
|
||||
/// \brief Returns whether this template declaration defines the primary
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace clang {
|
|||
class IdentifierInfo;
|
||||
class MultiKeywordSelector;
|
||||
enum OverloadedOperatorKind : int;
|
||||
struct PrintingPolicy;
|
||||
class QualType;
|
||||
class Type;
|
||||
class TypeSourceInfo;
|
||||
|
|
@ -302,7 +303,9 @@ public:
|
|||
}
|
||||
|
||||
static int compare(DeclarationName LHS, DeclarationName RHS);
|
||||
|
||||
|
||||
void print(raw_ostream &OS, const PrintingPolicy &Policy);
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/AtomicOrdering.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace clang {
|
||||
|
|
@ -593,6 +594,13 @@ public:
|
|||
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
|
||||
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
|
||||
|
||||
/// EvaluateAsFloat - Return true if this is a constant which we can fold and
|
||||
/// convert to a floating point value, using any crazy technique that we
|
||||
/// want to.
|
||||
bool
|
||||
EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,
|
||||
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
|
||||
|
||||
/// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
|
||||
/// constant folded without side-effects, but discard the result.
|
||||
bool isEvaluatable(const ASTContext &Ctx,
|
||||
|
|
@ -847,10 +855,12 @@ public:
|
|||
ExprObjectKind OK = OK_Ordinary,
|
||||
Expr *SourceExpr = nullptr)
|
||||
: Expr(OpaqueValueExprClass, T, VK, OK,
|
||||
T->isDependentType(),
|
||||
T->isDependentType() ||
|
||||
(SourceExpr && SourceExpr->isTypeDependent()),
|
||||
T->isDependentType() ||
|
||||
(SourceExpr && SourceExpr->isValueDependent()),
|
||||
T->isInstantiationDependentType(),
|
||||
T->isInstantiationDependentType() ||
|
||||
(SourceExpr && SourceExpr->isInstantiationDependent()),
|
||||
false),
|
||||
SourceExpr(SourceExpr), Loc(Loc) {
|
||||
}
|
||||
|
|
@ -1110,6 +1120,10 @@ public:
|
|||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
|
||||
}
|
||||
|
||||
ArrayRef<TemplateArgumentLoc> template_arguments() const {
|
||||
return {getTemplateArgs(), getNumTemplateArgs()};
|
||||
}
|
||||
|
||||
/// \brief Returns true if this expression refers to a function that
|
||||
/// was resolved from an overloaded set having size greater than 1.
|
||||
bool hadMultipleCandidates() const {
|
||||
|
|
@ -2137,11 +2151,15 @@ class CallExpr : public Expr {
|
|||
unsigned NumArgs;
|
||||
SourceLocation RParenLoc;
|
||||
|
||||
void updateDependenciesFromArg(Expr *Arg);
|
||||
|
||||
protected:
|
||||
// These versions of the constructor are for derived classes.
|
||||
CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
|
||||
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
|
||||
SourceLocation rparenloc);
|
||||
CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
|
||||
ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
|
||||
ExprValueKind VK, SourceLocation rparenloc);
|
||||
CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args,
|
||||
QualType t, ExprValueKind VK, SourceLocation rparenloc);
|
||||
CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
|
||||
EmptyShell Empty);
|
||||
|
||||
|
|
@ -2477,6 +2495,10 @@ public:
|
|||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
|
||||
}
|
||||
|
||||
ArrayRef<TemplateArgumentLoc> template_arguments() const {
|
||||
return {getTemplateArgs(), getNumTemplateArgs()};
|
||||
}
|
||||
|
||||
/// \brief Retrieve the member declaration name info.
|
||||
DeclarationNameInfo getMemberNameInfo() const {
|
||||
return DeclarationNameInfo(MemberDecl->getDeclName(),
|
||||
|
|
@ -3942,7 +3964,7 @@ private:
|
|||
|
||||
/// Whether this designated initializer used the GNU deprecated
|
||||
/// syntax rather than the C99 '=' syntax.
|
||||
bool GNUSyntax : 1;
|
||||
unsigned GNUSyntax : 1;
|
||||
|
||||
/// The number of designators in this initializer expression.
|
||||
unsigned NumDesignators : 15;
|
||||
|
|
@ -3956,11 +3978,10 @@ private:
|
|||
/// expression.
|
||||
Designator *Designators;
|
||||
|
||||
|
||||
DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators,
|
||||
const Designator *Designators,
|
||||
DesignatedInitExpr(const ASTContext &C, QualType Ty,
|
||||
llvm::ArrayRef<Designator> Designators,
|
||||
SourceLocation EqualOrColonLoc, bool GNUSyntax,
|
||||
ArrayRef<Expr*> IndexExprs, Expr *Init);
|
||||
ArrayRef<Expr *> IndexExprs, Expr *Init);
|
||||
|
||||
explicit DesignatedInitExpr(unsigned NumSubExprs)
|
||||
: Expr(DesignatedInitExprClass, EmptyShell()),
|
||||
|
|
@ -4120,8 +4141,7 @@ public:
|
|||
};
|
||||
|
||||
static DesignatedInitExpr *Create(const ASTContext &C,
|
||||
Designator *Designators,
|
||||
unsigned NumDesignators,
|
||||
llvm::ArrayRef<Designator> Designators,
|
||||
ArrayRef<Expr*> IndexExprs,
|
||||
SourceLocation EqualOrColonLoc,
|
||||
bool GNUSyntax, Expr *Init);
|
||||
|
|
@ -4133,48 +4153,15 @@ public:
|
|||
unsigned size() const { return NumDesignators; }
|
||||
|
||||
// Iterator access to the designators.
|
||||
typedef Designator *designators_iterator;
|
||||
designators_iterator designators_begin() { return Designators; }
|
||||
designators_iterator designators_end() {
|
||||
return Designators + NumDesignators;
|
||||
llvm::MutableArrayRef<Designator> designators() {
|
||||
return {Designators, NumDesignators};
|
||||
}
|
||||
|
||||
typedef const Designator *const_designators_iterator;
|
||||
const_designators_iterator designators_begin() const { return Designators; }
|
||||
const_designators_iterator designators_end() const {
|
||||
return Designators + NumDesignators;
|
||||
llvm::ArrayRef<Designator> designators() const {
|
||||
return {Designators, NumDesignators};
|
||||
}
|
||||
|
||||
typedef llvm::iterator_range<designators_iterator> designators_range;
|
||||
designators_range designators() {
|
||||
return designators_range(designators_begin(), designators_end());
|
||||
}
|
||||
|
||||
typedef llvm::iterator_range<const_designators_iterator>
|
||||
designators_const_range;
|
||||
designators_const_range designators() const {
|
||||
return designators_const_range(designators_begin(), designators_end());
|
||||
}
|
||||
|
||||
typedef std::reverse_iterator<designators_iterator>
|
||||
reverse_designators_iterator;
|
||||
reverse_designators_iterator designators_rbegin() {
|
||||
return reverse_designators_iterator(designators_end());
|
||||
}
|
||||
reverse_designators_iterator designators_rend() {
|
||||
return reverse_designators_iterator(designators_begin());
|
||||
}
|
||||
|
||||
typedef std::reverse_iterator<const_designators_iterator>
|
||||
const_reverse_designators_iterator;
|
||||
const_reverse_designators_iterator designators_rbegin() const {
|
||||
return const_reverse_designators_iterator(designators_end());
|
||||
}
|
||||
const_reverse_designators_iterator designators_rend() const {
|
||||
return const_reverse_designators_iterator(designators_begin());
|
||||
}
|
||||
|
||||
Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
|
||||
Designator *getDesignator(unsigned Idx) { return &designators()[Idx]; }
|
||||
|
||||
void setDesignators(const ASTContext &C, const Designator *Desigs,
|
||||
unsigned NumDesigs);
|
||||
|
|
@ -4824,16 +4811,6 @@ public:
|
|||
BI_First = 0
|
||||
};
|
||||
|
||||
// The ABI values for various atomic memory orderings.
|
||||
enum AtomicOrderingKind {
|
||||
AO_ABI_memory_order_relaxed = 0,
|
||||
AO_ABI_memory_order_consume = 1,
|
||||
AO_ABI_memory_order_acquire = 2,
|
||||
AO_ABI_memory_order_release = 3,
|
||||
AO_ABI_memory_order_acq_rel = 4,
|
||||
AO_ABI_memory_order_seq_cst = 5
|
||||
};
|
||||
|
||||
private:
|
||||
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
|
||||
Stmt* SubExprs[END_EXPR];
|
||||
|
|
@ -4882,9 +4859,12 @@ public:
|
|||
}
|
||||
|
||||
AtomicOp getOp() const { return Op; }
|
||||
unsigned getNumSubExprs() { return NumSubExprs; }
|
||||
unsigned getNumSubExprs() const { return NumSubExprs; }
|
||||
|
||||
Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
|
||||
const Expr * const *getSubExprs() const {
|
||||
return reinterpret_cast<Expr * const *>(SubExprs);
|
||||
}
|
||||
|
||||
bool isVolatile() const {
|
||||
return getPtr()->getType()->getPointeeType().isVolatileQualified();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#define LLVM_CLANG_AST_EXPRCXX_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/LambdaCapture.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
|
|
@ -26,9 +27,6 @@
|
|||
|
||||
namespace clang {
|
||||
|
||||
class CXXConstructorDecl;
|
||||
class CXXDestructorDecl;
|
||||
class CXXMethodDecl;
|
||||
class CXXTemporary;
|
||||
class MSPropertyDecl;
|
||||
class TemplateArgumentListInfo;
|
||||
|
|
@ -66,8 +64,7 @@ public:
|
|||
CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
|
||||
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
|
||||
SourceLocation operatorloc, bool fpContractable)
|
||||
: CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
|
||||
operatorloc),
|
||||
: CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
|
||||
Operator(Op), FPContractable(fpContractable) {
|
||||
Range = getSourceRangeImpl();
|
||||
}
|
||||
|
|
@ -125,7 +122,7 @@ class CXXMemberCallExpr : public CallExpr {
|
|||
public:
|
||||
CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
|
||||
QualType t, ExprValueKind VK, SourceLocation RP)
|
||||
: CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {}
|
||||
: CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {}
|
||||
|
||||
CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
|
||||
: CallExpr(C, CXXMemberCallExprClass, Empty) { }
|
||||
|
|
@ -146,6 +143,14 @@ public:
|
|||
/// FIXME: Returns 0 for member pointer call exprs.
|
||||
CXXRecordDecl *getRecordDecl() const;
|
||||
|
||||
SourceLocation getExprLoc() const LLVM_READONLY {
|
||||
SourceLocation CLoc = getCallee()->getExprLoc();
|
||||
if (CLoc.isValid())
|
||||
return CLoc;
|
||||
|
||||
return getLocStart();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXMemberCallExprClass;
|
||||
}
|
||||
|
|
@ -160,9 +165,7 @@ public:
|
|||
CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
|
||||
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
|
||||
SourceLocation RP)
|
||||
: CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) {
|
||||
setConfig(Config);
|
||||
}
|
||||
: CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {}
|
||||
|
||||
CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
|
||||
: CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { }
|
||||
|
|
@ -171,7 +174,20 @@ public:
|
|||
return cast_or_null<CallExpr>(getPreArg(CONFIG));
|
||||
}
|
||||
CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
|
||||
void setConfig(CallExpr *E) { setPreArg(CONFIG, E); }
|
||||
|
||||
/// \brief Sets the kernel configuration expression.
|
||||
///
|
||||
/// Note that this method cannot be called if config has already been set to a
|
||||
/// non-null value.
|
||||
void setConfig(CallExpr *E) {
|
||||
assert(!getConfig() &&
|
||||
"Cannot call setConfig if config is not null");
|
||||
setPreArg(CONFIG, E);
|
||||
setInstantiationDependent(isInstantiationDependent() ||
|
||||
E->isInstantiationDependent());
|
||||
setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() ||
|
||||
E->containsUnexpandedParameterPack());
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CUDAKernelCallExprClass;
|
||||
|
|
@ -398,7 +414,7 @@ public:
|
|||
UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
|
||||
QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
|
||||
SourceLocation SuffixLoc)
|
||||
: CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc),
|
||||
: CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc),
|
||||
UDSuffixLoc(SuffixLoc) {}
|
||||
explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
|
||||
: CallExpr(C, UserDefinedLiteralClass, Empty) {}
|
||||
|
|
@ -768,22 +784,23 @@ public:
|
|||
class CXXUuidofExpr : public Expr {
|
||||
private:
|
||||
llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
|
||||
StringRef UuidStr;
|
||||
SourceRange Range;
|
||||
|
||||
public:
|
||||
CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
|
||||
false, Operand->getType()->isDependentType(),
|
||||
Operand->getType()->isInstantiationDependentType(),
|
||||
Operand->getType()->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), Range(R) { }
|
||||
CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr,
|
||||
SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
|
||||
Operand->getType()->isDependentType(),
|
||||
Operand->getType()->isInstantiationDependentType(),
|
||||
Operand->getType()->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), UuidStr(UuidStr), Range(R) {}
|
||||
|
||||
CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
|
||||
false, Operand->isTypeDependent(),
|
||||
Operand->isInstantiationDependent(),
|
||||
Operand->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), Range(R) { }
|
||||
CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
|
||||
Operand->isTypeDependent(), Operand->isInstantiationDependent(),
|
||||
Operand->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), UuidStr(UuidStr), Range(R) {}
|
||||
|
||||
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
|
||||
: Expr(CXXUuidofExprClass, Empty) {
|
||||
|
|
@ -820,7 +837,8 @@ public:
|
|||
Operand = E;
|
||||
}
|
||||
|
||||
StringRef getUuidAsStringRef(ASTContext &Context) const;
|
||||
void setUuidStr(StringRef US) { UuidStr = US; }
|
||||
StringRef getUuidStr() const { return UuidStr; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
|
||||
|
|
@ -831,11 +849,6 @@ public:
|
|||
return T->getStmtClass() == CXXUuidofExprClass;
|
||||
}
|
||||
|
||||
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
|
||||
/// a single GUID.
|
||||
static const UuidAttr *GetUuidAttrOfType(QualType QT,
|
||||
bool *HasMultipleGUIDsPtr = nullptr);
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
if (isTypeOperand())
|
||||
|
|
@ -1161,18 +1174,21 @@ private:
|
|||
SourceLocation Loc;
|
||||
SourceRange ParenOrBraceRange;
|
||||
unsigned NumArgs : 16;
|
||||
bool Elidable : 1;
|
||||
bool HadMultipleCandidates : 1;
|
||||
bool ListInitialization : 1;
|
||||
bool StdInitListInitialization : 1;
|
||||
bool ZeroInitialization : 1;
|
||||
unsigned Elidable : 1;
|
||||
unsigned HadMultipleCandidates : 1;
|
||||
unsigned ListInitialization : 1;
|
||||
unsigned StdInitListInitialization : 1;
|
||||
unsigned ZeroInitialization : 1;
|
||||
unsigned ConstructKind : 2;
|
||||
Stmt **Args;
|
||||
|
||||
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
|
||||
|
||||
protected:
|
||||
CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *d, bool elidable,
|
||||
CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr *> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
|
|
@ -1191,15 +1207,12 @@ protected:
|
|||
public:
|
||||
/// \brief Construct an empty C++ construction expression.
|
||||
explicit CXXConstructExpr(EmptyShell Empty)
|
||||
: Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
|
||||
NumArgs(0), Elidable(false), HadMultipleCandidates(false),
|
||||
ListInitialization(false), ZeroInitialization(false),
|
||||
ConstructKind(0), Args(nullptr)
|
||||
{ }
|
||||
: CXXConstructExpr(CXXConstructExprClass, Empty) {}
|
||||
|
||||
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *D, bool Elidable,
|
||||
CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr *> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
|
|
@ -1208,8 +1221,8 @@ public:
|
|||
ConstructionKind ConstructKind,
|
||||
SourceRange ParenOrBraceRange);
|
||||
|
||||
/// \brief Get the constructor that this expression will (ultimately) call.
|
||||
CXXConstructorDecl *getConstructor() const { return Constructor; }
|
||||
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
|
||||
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
void setLocation(SourceLocation Loc) { this->Loc = Loc; }
|
||||
|
|
@ -1305,6 +1318,73 @@ public:
|
|||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// \brief Represents a call to an inherited base class constructor from an
|
||||
/// inheriting constructor. This call implicitly forwards the arguments from
|
||||
/// the enclosing context (an inheriting constructor) to the specified inherited
|
||||
/// base class constructor.
|
||||
class CXXInheritedCtorInitExpr : public Expr {
|
||||
private:
|
||||
CXXConstructorDecl *Constructor;
|
||||
|
||||
/// The location of the using declaration.
|
||||
SourceLocation Loc;
|
||||
|
||||
/// Whether this is the construction of a virtual base.
|
||||
unsigned ConstructsVirtualBase : 1;
|
||||
|
||||
/// Whether the constructor is inherited from a virtual base class of the
|
||||
/// class that we construct.
|
||||
unsigned InheritedFromVirtualBase : 1;
|
||||
|
||||
public:
|
||||
/// \brief Construct a C++ inheriting construction expression.
|
||||
CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
|
||||
CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
|
||||
bool InheritedFromVirtualBase)
|
||||
: Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false,
|
||||
false, false, false),
|
||||
Constructor(Ctor), Loc(Loc),
|
||||
ConstructsVirtualBase(ConstructsVirtualBase),
|
||||
InheritedFromVirtualBase(InheritedFromVirtualBase) {
|
||||
assert(!T->isDependentType());
|
||||
}
|
||||
|
||||
/// \brief Construct an empty C++ inheriting construction expression.
|
||||
explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
|
||||
: Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr),
|
||||
ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
|
||||
|
||||
/// \brief Get the constructor that this expression will call.
|
||||
CXXConstructorDecl *getConstructor() const { return Constructor; }
|
||||
|
||||
/// \brief Determine whether this constructor is actually constructing
|
||||
/// a base class (rather than a complete object).
|
||||
bool constructsVBase() const { return ConstructsVirtualBase; }
|
||||
CXXConstructExpr::ConstructionKind getConstructionKind() const {
|
||||
return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase
|
||||
: CXXConstructExpr::CK_NonVirtualBase;
|
||||
}
|
||||
|
||||
/// \brief Determine whether the inherited constructor is inherited from a
|
||||
/// virtual base of the object we construct. If so, we are not responsible
|
||||
/// for calling the inherited constructor (the complete object constructor
|
||||
/// does that), and so we don't need to pass any arguments.
|
||||
bool inheritedFromVBase() const { return InheritedFromVirtualBase; }
|
||||
|
||||
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXInheritedCtorInitExprClass;
|
||||
}
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// \brief Represents an explicit C++ type conversion that uses "functional"
|
||||
/// notation (C++ [expr.type.conv]).
|
||||
///
|
||||
|
|
@ -1375,7 +1455,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
|
|||
TypeSourceInfo *Type;
|
||||
|
||||
public:
|
||||
CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
|
||||
CXXTemporaryObjectExpr(const ASTContext &C,
|
||||
CXXConstructorDecl *Cons,
|
||||
TypeSourceInfo *Type,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceRange ParenOrBraceRange,
|
||||
|
|
@ -1744,12 +1825,12 @@ class CXXNewExpr : public Expr {
|
|||
SourceRange DirectInitRange;
|
||||
|
||||
/// Was the usage ::new, i.e. is the global new to be used?
|
||||
bool GlobalNew : 1;
|
||||
unsigned GlobalNew : 1;
|
||||
/// Do we allocate an array? If so, the first SubExpr is the size expression.
|
||||
bool Array : 1;
|
||||
unsigned Array : 1;
|
||||
/// If this is an array allocation, does the usual deallocation
|
||||
/// function for the allocated type want to know the allocated size?
|
||||
bool UsualArrayDeleteWantsSize : 1;
|
||||
unsigned UsualArrayDeleteWantsSize : 1;
|
||||
/// The number of placement new arguments.
|
||||
unsigned NumPlacementArgs : 13;
|
||||
/// What kind of initializer do we have? Could be none, parens, or braces.
|
||||
|
|
@ -2348,7 +2429,7 @@ class ExpressionTraitExpr : public Expr {
|
|||
/// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
|
||||
unsigned ET : 31;
|
||||
/// \brief The value of the type trait. Unspecified if dependent.
|
||||
bool Value : 1;
|
||||
unsigned Value : 1;
|
||||
|
||||
/// \brief The location of the type trait keyword.
|
||||
SourceLocation Loc;
|
||||
|
|
@ -2557,6 +2638,10 @@ public:
|
|||
return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
|
||||
}
|
||||
|
||||
ArrayRef<TemplateArgumentLoc> template_arguments() const {
|
||||
return {getTemplateArgs(), getNumTemplateArgs()};
|
||||
}
|
||||
|
||||
/// \brief Copies the template arguments into the given structure.
|
||||
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
|
||||
if (hasExplicitTemplateArgs())
|
||||
|
|
@ -2810,6 +2895,10 @@ public:
|
|||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
|
||||
}
|
||||
|
||||
ArrayRef<TemplateArgumentLoc> template_arguments() const {
|
||||
return {getTemplateArgs(), getNumTemplateArgs()};
|
||||
}
|
||||
|
||||
/// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
|
||||
/// and differs from getLocation().getStart().
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
|
|
@ -2858,7 +2947,8 @@ private:
|
|||
Stmt *SubExpr;
|
||||
|
||||
ExprWithCleanups(EmptyShell, unsigned NumObjects);
|
||||
ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
|
||||
ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
|
||||
ArrayRef<CleanupObject> Objects);
|
||||
|
||||
friend TrailingObjects;
|
||||
friend class ASTStmtReader;
|
||||
|
|
@ -2868,6 +2958,7 @@ public:
|
|||
unsigned numObjects);
|
||||
|
||||
static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
|
||||
bool CleanupsHaveSideEffects,
|
||||
ArrayRef<CleanupObject> objects);
|
||||
|
||||
ArrayRef<CleanupObject> getObjects() const {
|
||||
|
|
@ -2884,6 +2975,9 @@ public:
|
|||
|
||||
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
|
||||
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
|
||||
bool cleanupsHaveSideEffects() const {
|
||||
return ExprWithCleanupsBits.CleanupsHaveSideEffects;
|
||||
}
|
||||
|
||||
/// As with any mutator of the AST, be very careful
|
||||
/// when modifying an existing AST to preserve its invariants.
|
||||
|
|
@ -3220,6 +3314,10 @@ public:
|
|||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
|
||||
}
|
||||
|
||||
ArrayRef<TemplateArgumentLoc> template_arguments() const {
|
||||
return {getTemplateArgs(), getNumTemplateArgs()};
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
if (!isImplicitAccess())
|
||||
return Base->getLocStart();
|
||||
|
|
|
|||
|
|
@ -1562,7 +1562,52 @@ public:
|
|||
return T->getStmtClass() == ObjCBridgedCastExprClass;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief A runtime availability query.
|
||||
///
|
||||
/// There are 2 ways to spell this node:
|
||||
/// \code
|
||||
/// @available(macos 10.10, ios 8, *); // Objective-C
|
||||
/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C
|
||||
/// \endcode
|
||||
///
|
||||
/// Note that we only need to keep track of one \c VersionTuple here, which is
|
||||
/// the one that corresponds to the current deployment target. This is meant to
|
||||
/// be used in the condition of an \c if, but it is also usable as top level
|
||||
/// expressions.
|
||||
///
|
||||
class ObjCAvailabilityCheckExpr : public Expr {
|
||||
VersionTuple VersionToCheck;
|
||||
SourceLocation AtLoc, RParen;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
|
||||
SourceLocation RParen, QualType Ty)
|
||||
: Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false,
|
||||
false, false, false),
|
||||
VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {}
|
||||
|
||||
explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
|
||||
: Expr(ObjCAvailabilityCheckExprClass, Shell) {}
|
||||
|
||||
SourceLocation getLocStart() const { return AtLoc; }
|
||||
SourceLocation getLocEnd() const { return RParen; }
|
||||
SourceRange getSourceRange() const { return {AtLoc, RParen}; }
|
||||
|
||||
/// \brief This may be '*', in which case this should fold to true.
|
||||
bool hasVersion() const { return !VersionToCheck.empty(); }
|
||||
VersionTuple getVersion() { return VersionToCheck; }
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public:
|
|||
void setBase(Expr *E) { SubExprs[BASE] = E; }
|
||||
|
||||
/// \brief Return original type of the base expression for array section.
|
||||
static QualType getBaseOriginalType(Expr *Base);
|
||||
static QualType getBaseOriginalType(const Expr *Base);
|
||||
|
||||
/// \brief Get lower bound of array section.
|
||||
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclOpenMP.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
|
||||
namespace clang {
|
||||
|
|
@ -43,6 +44,7 @@ public:
|
|||
GlobalDecl(const BlockDecl *D) { Init(D); }
|
||||
GlobalDecl(const CapturedDecl *D) { Init(D); }
|
||||
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
|
||||
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
|
||||
|
||||
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
|
||||
: Value(D, Type) {}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,22 @@ class LambdaCapture {
|
|||
/// given capture was by-copy.
|
||||
///
|
||||
/// This includes the case of a non-reference init-capture.
|
||||
Capture_ByCopy = 0x02
|
||||
Capture_ByCopy = 0x02,
|
||||
|
||||
/// \brief Flag used by the Capture class to distinguish between a capture
|
||||
/// of '*this' and a capture of a VLA type.
|
||||
Capture_This = 0x04
|
||||
};
|
||||
|
||||
llvm::PointerIntPair<Decl *, 2> DeclAndBits;
|
||||
// Decl could represent:
|
||||
// - a VarDecl* that represents the variable that was captured or the
|
||||
// init-capture.
|
||||
// - or, is a nullptr and Capture_This is set in Bits if this represents a
|
||||
// capture of '*this' by value or reference.
|
||||
// - or, is a nullptr and Capture_This is not set in Bits if this represents
|
||||
// a capture of a VLA type.
|
||||
llvm::PointerIntPair<Decl*, 3> DeclAndBits;
|
||||
|
||||
SourceLocation Loc;
|
||||
SourceLocation EllipsisLoc;
|
||||
|
||||
|
|
@ -69,8 +81,8 @@ public:
|
|||
/// \brief Determine whether this capture handles the C++ \c this
|
||||
/// pointer.
|
||||
bool capturesThis() const {
|
||||
return (DeclAndBits.getPointer() == nullptr) &&
|
||||
!(DeclAndBits.getInt() & Capture_ByCopy);
|
||||
return DeclAndBits.getPointer() == nullptr &&
|
||||
(DeclAndBits.getInt() & Capture_This);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this capture handles a variable.
|
||||
|
|
@ -81,8 +93,8 @@ public:
|
|||
/// \brief Determine whether this captures a variable length array bound
|
||||
/// expression.
|
||||
bool capturesVLAType() const {
|
||||
return (DeclAndBits.getPointer() == nullptr) &&
|
||||
(DeclAndBits.getInt() & Capture_ByCopy);
|
||||
return DeclAndBits.getPointer() == nullptr &&
|
||||
!(DeclAndBits.getInt() & Capture_This);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the declaration of the local variable being
|
||||
|
|
@ -91,13 +103,15 @@ public:
|
|||
/// This operation is only valid if this capture is a variable capture
|
||||
/// (other than a capture of \c this).
|
||||
VarDecl *getCapturedVar() const {
|
||||
assert(capturesVariable() && "No variable available for 'this' capture");
|
||||
return cast<VarDecl>(DeclAndBits.getPointer());
|
||||
assert(capturesVariable() && "No variable available for capture");
|
||||
return static_cast<VarDecl *>(DeclAndBits.getPointer());
|
||||
}
|
||||
|
||||
/// \brief Determine whether this was an implicit capture (not
|
||||
/// written between the square brackets introducing the lambda).
|
||||
bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
|
||||
bool isImplicit() const {
|
||||
return DeclAndBits.getInt() & Capture_Implicit;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this was an explicit capture (written
|
||||
/// between the square brackets introducing the lambda).
|
||||
|
|
|
|||
|
|
@ -36,11 +36,10 @@ class LocInfoType : public Type {
|
|||
TypeSourceInfo *DeclInfo;
|
||||
|
||||
LocInfoType(QualType ty, TypeSourceInfo *TInfo)
|
||||
: Type((TypeClass)LocInfo, ty, ty->isDependentType(),
|
||||
ty->isInstantiationDependentType(),
|
||||
ty->isVariablyModifiedType(),
|
||||
ty->containsUnexpandedParameterPack()),
|
||||
DeclInfo(TInfo) {
|
||||
: Type((TypeClass)LocInfo, ty, ty->isDependentType(),
|
||||
ty->isInstantiationDependentType(), ty->isVariablyModifiedType(),
|
||||
ty->containsUnexpandedParameterPack()),
|
||||
DeclInfo(TInfo) {
|
||||
assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
|
||||
}
|
||||
friend class Sema;
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
CLANG_LEVEL := ../../..
|
||||
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
|
||||
BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \
|
||||
StmtNodes.inc DeclNodes.inc \
|
||||
CommentNodes.inc CommentHTMLTags.inc \
|
||||
CommentHTMLTagsProperties.inc \
|
||||
CommentHTMLNamedCharacterReferences.inc \
|
||||
CommentCommandInfo.inc \
|
||||
CommentCommandList.inc
|
||||
|
||||
TABLEGEN_INC_FILES_COMMON = 1
|
||||
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang attribute classes with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
|
||||
-I $(PROJ_SRC_DIR)/../../ $<
|
||||
|
||||
$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang attribute implementations with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
|
||||
-I $(PROJ_SRC_DIR)/../../ $<
|
||||
|
||||
$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang attribute dumper with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
|
||||
-I $(PROJ_SRC_DIR)/../../ $<
|
||||
|
||||
$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang attribute AST visitor with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \
|
||||
-I $(PROJ_SRC_DIR)/../../ $<
|
||||
|
||||
$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang statement node tables with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang declaration node tables with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang comment node tables with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \
|
||||
$(ObjDir)/.dir
|
||||
$(Echo) "Building Clang comment HTML tag matchers with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \
|
||||
$(CLANG_TBLGEN) $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang comment HTML tag properties with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \
|
||||
$(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \
|
||||
$(CLANG_TBLGEN) $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang named character reference translation function with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
|
||||
$(CLANG_TBLGEN) $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang comment command info with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
|
||||
$(CLANG_TBLGEN) $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang list of comment commands with tblgen"
|
||||
$(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $<
|
||||
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_CLANG_AST_MANGLE_H
|
||||
#define LLVM_CLANG_AST_MANGLE_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
|
@ -123,6 +124,7 @@ public:
|
|||
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
|
||||
raw_ostream &Out);
|
||||
|
||||
void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
|
||||
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
|
||||
|
||||
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
|
||||
|
|
@ -206,7 +208,8 @@ public:
|
|||
raw_ostream &Out) = 0;
|
||||
|
||||
virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
|
||||
uint32_t NumEntries, raw_ostream &Out) = 0;
|
||||
bool IsUnaligned, uint32_t NumEntries,
|
||||
raw_ostream &Out) = 0;
|
||||
|
||||
virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
|
||||
raw_ostream &Out) = 0;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue