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
@ -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 @@ def __getitem__(self, key):
|
||||
|
||||
return FixItIterator(self)
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
class ChildDiagnosticsIterator:
|
||||
def __init__(self, diag):
|
||||
self.diag_set = conf.lib.clang_getChildDiagnostics(diag)
|
||||
|
||||
def __len__(self):
|
||||
return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set))
|
||||
|
||||
def __getitem__(self, key):
|
||||
diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key)
|
||||
if not diag:
|
||||
raise IndexError
|
||||
return Diagnostic(diag)
|
||||
|
||||
return ChildDiagnosticsIterator(self)
|
||||
|
||||
@property
|
||||
def category_number(self):
|
||||
"""The category number for this diagnostic or 0 if unavailable."""
|
||||
@ -1120,6 +1137,9 @@ def __repr__(self):
|
||||
# A type alias template declaration
|
||||
CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601)
|
||||
|
||||
# A code completion overload candidate.
|
||||
CursorKind.OVERLOAD_CANDIDATE = CursorKind(700)
|
||||
|
||||
### Template Argument Kinds ###
|
||||
class TemplateArgumentKind(BaseEnumeration):
|
||||
"""
|
||||
@ -1174,6 +1194,32 @@ def is_const_method(self):
|
||||
"""
|
||||
return conf.lib.clang_CXXMethod_isConst(self)
|
||||
|
||||
def is_converting_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ converting constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isConvertingConstructor(self)
|
||||
|
||||
def is_copy_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ copy constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isCopyConstructor(self)
|
||||
|
||||
def is_default_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ default constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isDefaultConstructor(self)
|
||||
|
||||
def is_move_constructor(self):
|
||||
"""Returns True if the cursor refers to a C++ move constructor.
|
||||
"""
|
||||
return conf.lib.clang_CXXConstructor_isMoveConstructor(self)
|
||||
|
||||
def is_default_method(self):
|
||||
"""Returns True if the cursor refers to a C++ member function or member
|
||||
function template that is declared '= default'.
|
||||
"""
|
||||
return conf.lib.clang_CXXMethod_isDefaulted(self)
|
||||
|
||||
def is_mutable_field(self):
|
||||
"""Returns True if the cursor refers to a C++ field that is declared
|
||||
'mutable'.
|
||||
@ -1685,6 +1731,7 @@ def __repr__(self):
|
||||
TypeKind.OBJCID = TypeKind(27)
|
||||
TypeKind.OBJCCLASS = TypeKind(28)
|
||||
TypeKind.OBJCSEL = TypeKind(29)
|
||||
TypeKind.FLOAT128 = TypeKind(30)
|
||||
TypeKind.COMPLEX = TypeKind(100)
|
||||
TypeKind.POINTER = TypeKind(101)
|
||||
TypeKind.BLOCKPOINTER = TypeKind(102)
|
||||
@ -1704,6 +1751,7 @@ def __repr__(self):
|
||||
TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
|
||||
TypeKind.MEMBERPOINTER = TypeKind(117)
|
||||
TypeKind.AUTO = TypeKind(118)
|
||||
TypeKind.ELABORATED = TypeKind(119)
|
||||
|
||||
class RefQualifierKind(BaseEnumeration):
|
||||
"""Describes a specific ref-qualifier of a type."""
|
||||
@ -1902,6 +1950,12 @@ def get_class_type(self):
|
||||
"""
|
||||
return conf.lib.clang_Type_getClassType(self)
|
||||
|
||||
def get_named_type(self):
|
||||
"""
|
||||
Retrieve the type named by the qualified-id.
|
||||
"""
|
||||
return conf.lib.clang_Type_getNamedType(self)
|
||||
|
||||
def get_align(self):
|
||||
"""
|
||||
Retrieve the alignment of the record.
|
||||
@ -2383,7 +2437,7 @@ def __init__(self, ptr, index):
|
||||
functions above. __init__ is only called internally.
|
||||
"""
|
||||
assert isinstance(index, Index)
|
||||
|
||||
self.index = index
|
||||
ClangObject.__init__(self, ptr)
|
||||
|
||||
def __del__(self):
|
||||
@ -2702,6 +2756,11 @@ def directory(self):
|
||||
"""Get the working directory for this CompileCommand"""
|
||||
return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
"""Get the working filename for this CompileCommand"""
|
||||
return conf.lib.clang_CompileCommand_getFilename(self.cmd)
|
||||
|
||||
@property
|
||||
def arguments(self):
|
||||
"""
|
||||
@ -2884,6 +2943,11 @@ def cursor(self):
|
||||
_CXString,
|
||||
_CXString.from_result),
|
||||
|
||||
("clang_CompileCommand_getFilename",
|
||||
[c_object_p],
|
||||
_CXString,
|
||||
_CXString.from_result),
|
||||
|
||||
("clang_CompileCommand_getNumArgs",
|
||||
[c_object_p],
|
||||
c_uint),
|
||||
@ -2908,6 +2972,22 @@ def cursor(self):
|
||||
[Index, c_char_p],
|
||||
c_object_p),
|
||||
|
||||
("clang_CXXConstructor_isConvertingConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXConstructor_isCopyConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXConstructor_isDefaultConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXConstructor_isMoveConstructor",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXField_isMutable",
|
||||
[Cursor],
|
||||
bool),
|
||||
@ -2916,6 +2996,10 @@ def cursor(self):
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXMethod_isDefaulted",
|
||||
[Cursor],
|
||||
bool),
|
||||
|
||||
("clang_CXXMethod_isPureVirtual",
|
||||
[Cursor],
|
||||
bool),
|
||||
@ -2997,6 +3081,10 @@ def cursor(self):
|
||||
Type,
|
||||
Type.from_result),
|
||||
|
||||
("clang_getChildDiagnostics",
|
||||
[Diagnostic],
|
||||
c_object_p),
|
||||
|
||||
("clang_getCompletionAvailability",
|
||||
[c_void_p],
|
||||
c_int),
|
||||
@ -3117,6 +3205,10 @@ def cursor(self):
|
||||
_CXString,
|
||||
_CXString.from_result),
|
||||
|
||||
("clang_getDiagnosticInSet",
|
||||
[c_object_p, c_uint],
|
||||
c_object_p),
|
||||
|
||||
("clang_getDiagnosticLocation",
|
||||
[Diagnostic],
|
||||
SourceLocation),
|
||||
@ -3218,6 +3310,10 @@ def cursor(self):
|
||||
[c_object_p],
|
||||
c_uint),
|
||||
|
||||
("clang_getNumDiagnosticsInSet",
|
||||
[c_object_p],
|
||||
c_uint),
|
||||
|
||||
("clang_getNumElements",
|
||||
[Type],
|
||||
c_longlong),
|
||||
@ -3477,6 +3573,11 @@ def cursor(self):
|
||||
[Type],
|
||||
c_uint),
|
||||
|
||||
("clang_Type_getNamedType",
|
||||
[Type],
|
||||
Type,
|
||||
Type.from_result),
|
||||
|
||||
("clang_Type_visitFields",
|
||||
[Type, callbacks['fields_visit'], py_object],
|
||||
c_uint),
|
||||
|
@ -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 @@
|
||||
|
||||
# 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 @@
|
||||
# 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 link_if_exists(m):
|
||||
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 @@ def sort_table(matcher_type, matcher_map):
|
||||
|
||||
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 @@ def __str__(self):
|
||||
class EnumValue:
|
||||
def __init__(self, name, comment):
|
||||
self.name = name
|
||||
self.comment = comment.strip()
|
||||
self.comment = comment
|
||||
|
||||
def __str__(self):
|
||||
return '* ``%s`` (in configuration: ``%s``)\n%s' % (
|
||||
@ -86,8 +88,12 @@ def __str__(self):
|
||||
doxygen2rst(indent(self.comment, 2)))
|
||||
|
||||
def clean_comment_line(line):
|
||||
if line == '/// \\code':
|
||||
return '\n.. code-block:: c++\n\n'
|
||||
match = re.match(r'^/// \\code(\{.(\w+)\})?$', line)
|
||||
if match:
|
||||
lang = match.groups()[1]
|
||||
if not lang:
|
||||
lang = 'c++'
|
||||
return '\n.. code-block:: %s\n\n' % lang
|
||||
if line == '/// \\endcode':
|
||||
return ''
|
||||
return line[4:] + '\n'
|
||||
|
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 @@ class CheckAction : public WrapperFrontendAction {
|
||||
bool BeginInvocation(CompilerInstance &CI) override;
|
||||
|
||||
public:
|
||||
CheckAction(FrontendAction *WrappedAction);
|
||||
CheckAction(std::unique_ptr<FrontendAction> WrappedAction);
|
||||
};
|
||||
|
||||
class ModifyAction : public WrapperFrontendAction {
|
||||
@ -30,7 +30,7 @@ class ModifyAction : public WrapperFrontendAction {
|
||||
bool BeginInvocation(CompilerInstance &CI) override;
|
||||
|
||||
public:
|
||||
ModifyAction(FrontendAction *WrappedAction);
|
||||
ModifyAction(std::unique_ptr<FrontendAction> WrappedAction);
|
||||
};
|
||||
|
||||
class MigrateSourceAction : public ASTFrontendAction {
|
||||
@ -49,7 +49,8 @@ class MigrateAction : public WrapperFrontendAction {
|
||||
bool BeginInvocation(CompilerInstance &CI) override;
|
||||
|
||||
public:
|
||||
MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
|
||||
MigrateAction(std::unique_ptr<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 @@ class ASTConsumer {
|
||||
/// \returns true to continue parsing, or false to abort parsing.
|
||||
virtual bool HandleTopLevelDecl(DeclGroupRef D);
|
||||
|
||||
/// \brief This callback is invoked each time an inline method definition is
|
||||
/// completed.
|
||||
virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
|
||||
/// \brief This callback is invoked each time an inline (method or friend)
|
||||
/// function definition in a class is completed.
|
||||
virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
|
||||
|
||||
/// HandleInterestingDecl - Handle the specified interesting declaration. This
|
||||
/// is called by the AST reader when deserializing things that might interest
|
||||
@ -94,21 +94,6 @@ class ASTConsumer {
|
||||
/// The default implementation passes it to HandleTopLevelDecl.
|
||||
virtual void HandleImplicitImportDecl(ImportDecl *D);
|
||||
|
||||
/// \brief Handle a pragma that appends to Linker Options. Currently this
|
||||
/// only exists to support Microsoft's #pragma comment(linker, "/foo").
|
||||
virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}
|
||||
|
||||
/// \brief Handle a pragma that emits a mismatch identifier and value to the
|
||||
/// object file for the linker to work with. Currently, this only exists to
|
||||
/// support Microsoft's #pragma detect_mismatch.
|
||||
virtual void HandleDetectMismatch(llvm::StringRef Name,
|
||||
llvm::StringRef Value) {}
|
||||
|
||||
/// \brief Handle a dependent library created by a pragma in the source.
|
||||
/// Currently this only exists to support Microsoft's
|
||||
/// #pragma comment(lib, "/foo").
|
||||
virtual void HandleDependentLibrary(llvm::StringRef Lib) {}
|
||||
|
||||
/// CompleteTentativeDefinition - Callback invoked at the end of a translation
|
||||
/// unit to notify the consumer that the given tentative definition should be
|
||||
/// completed.
|
||||
@ -120,6 +105,10 @@ class ASTConsumer {
|
||||
/// modified by the introduction of an implicit zero initializer.
|
||||
virtual void CompleteTentativeDefinition(VarDecl *D) {}
|
||||
|
||||
/// \brief Callback invoked when an MSInheritanceAttr has been attached to a
|
||||
/// CXXRecordDecl.
|
||||
virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
|
||||
|
||||
/// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
|
||||
// variable has been instantiated.
|
||||
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
|
||||
|
@ -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 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \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 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
TranslationUnitDecl *TUDecl;
|
||||
mutable ExternCContextDecl *ExternCContext;
|
||||
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
|
||||
mutable BuiltinTemplateDecl *TypePackElementDecl;
|
||||
|
||||
/// \brief The associated SourceManager object.a
|
||||
SourceManager &SourceMgr;
|
||||
@ -817,6 +825,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
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 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
ExternCContextDecl *getExternCContextDecl() const;
|
||||
BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
|
||||
BuiltinTemplateDecl *getTypePackElementDecl() const;
|
||||
|
||||
// Builtin Types.
|
||||
CanQualType VoidTy;
|
||||
@ -889,20 +901,19 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
|
||||
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
|
||||
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
|
||||
CanQualType FloatTy, DoubleTy, LongDoubleTy;
|
||||
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
|
||||
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
|
||||
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
|
||||
CanQualType Float128ComplexTy;
|
||||
CanQualType VoidPtrTy, NullPtrTy;
|
||||
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
|
||||
CanQualType BuiltinFnTy;
|
||||
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
|
||||
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
|
||||
CanQualType ObjCBuiltinBoolTy;
|
||||
CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
|
||||
CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy;
|
||||
CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy;
|
||||
CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy;
|
||||
CanQualType OCLImage3dTy;
|
||||
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
||||
CanQualType SingletonId;
|
||||
#include "clang/Basic/OpenCLImageTypes.def"
|
||||
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
|
||||
CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
|
||||
CanQualType OMPArraySectionTy;
|
||||
@ -966,9 +977,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief Retrieve the declaration for the 128-bit unsigned integer type.
|
||||
TypedefDecl *getUInt128Decl() const;
|
||||
|
||||
/// \brief Retrieve the declaration for a 128-bit float stub type.
|
||||
TypeDecl *getFloat128StubType() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Constructors
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -1229,13 +1237,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
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 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
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 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// if it hasn't yet been built.
|
||||
QualType getRawCFConstantStringType() const {
|
||||
if (CFConstantStringTypeDecl)
|
||||
return getTagDeclType(CFConstantStringTypeDecl);
|
||||
return getTypedefType(CFConstantStringTypeDecl);
|
||||
return QualType();
|
||||
}
|
||||
void setCFConstantStringType(QualType T);
|
||||
TypedefDecl *getCFConstantStringDecl() const;
|
||||
RecordDecl *getCFConstantStringTagDecl() const;
|
||||
|
||||
// This setter/getter represents the ObjC type for an NSConstantString.
|
||||
void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
|
||||
@ -1458,12 +1465,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return NSCopyingName;
|
||||
}
|
||||
|
||||
/// Retrieve the identifier 'bool'.
|
||||
IdentifierInfo *getBoolName() const {
|
||||
if (!BoolName)
|
||||
BoolName = &Idents.get("bool");
|
||||
return BoolName;
|
||||
}
|
||||
|
||||
IdentifierInfo *getMakeIntegerSeqName() const {
|
||||
if (!MakeIntegerSeqName)
|
||||
MakeIntegerSeqName = &Idents.get("__make_integer_seq");
|
||||
return MakeIntegerSeqName;
|
||||
}
|
||||
|
||||
IdentifierInfo *getTypePackElementName() const {
|
||||
if (!TypePackElementName)
|
||||
TypePackElementName = &Idents.get("__type_pack_element");
|
||||
return TypePackElementName;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the Objective-C "instancetype" type, if already known;
|
||||
/// otherwise, returns a NULL type;
|
||||
QualType getObjCInstanceType() {
|
||||
@ -2257,7 +2277,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
QualType mergeObjCGCQualifiers(QualType, QualType);
|
||||
|
||||
bool FunctionTypesMatchOnNSConsumedAttrs(
|
||||
bool doFunctionTypesMatchOnExtParameterInfos(
|
||||
const FunctionProtoType *FromFunctionType,
|
||||
const FunctionProtoType *ToFunctionType);
|
||||
|
||||
@ -2508,7 +2528,21 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \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 @@ class ASTMutationListener {
|
||||
/// \param D the declaration marked OpenMP threadprivate.
|
||||
virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
|
||||
|
||||
/// \brief A declaration is marked as OpenMP declaretarget which was not
|
||||
/// previously marked as declaretarget.
|
||||
///
|
||||
/// \param D the declaration marked OpenMP declaretarget.
|
||||
/// \param Attr the added attribute.
|
||||
virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
|
||||
const Attr *Attr) {}
|
||||
|
||||
/// \brief A definition has been made visible by being redefined locally.
|
||||
///
|
||||
/// \param D The definition that was previously not visible.
|
||||
|
@ -62,7 +62,9 @@ class ASTNodeKind {
|
||||
/// \}
|
||||
|
||||
/// \brief Returns \c true if \c this and \c Other represent the same kind.
|
||||
bool isSame(ASTNodeKind Other) const;
|
||||
bool isSame(ASTNodeKind Other) const {
|
||||
return KindId != NKI_None && KindId == Other.KindId;
|
||||
}
|
||||
|
||||
/// \brief Returns \c true only for the default \c ASTNodeKind()
|
||||
bool isNone() const { return KindId == NKI_None; }
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/AttrKinds.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/OpenMPKinds.h"
|
||||
#include "clang/Basic/Sanitizers.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
@ -50,11 +51,11 @@ class Attr {
|
||||
/// An index into the spelling list of an
|
||||
/// attribute defined in Attr.td file.
|
||||
unsigned SpellingListIndex : 4;
|
||||
bool Inherited : 1;
|
||||
bool IsPackExpansion : 1;
|
||||
bool Implicit : 1;
|
||||
bool IsLateParsed : 1;
|
||||
bool DuplicatesAllowed : 1;
|
||||
unsigned Inherited : 1;
|
||||
unsigned IsPackExpansion : 1;
|
||||
unsigned Implicit : 1;
|
||||
unsigned IsLateParsed : 1;
|
||||
unsigned DuplicatesAllowed : 1;
|
||||
|
||||
void *operator new(size_t bytes) LLVM_NOEXCEPT {
|
||||
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
|
||||
@ -118,6 +119,19 @@ class Attr {
|
||||
bool duplicatesAllowed() const { return DuplicatesAllowed; }
|
||||
};
|
||||
|
||||
class StmtAttr : public Attr {
|
||||
protected:
|
||||
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed, bool DuplicatesAllowed)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
|
||||
|
||||
public:
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() >= attr::FirstStmtAttr &&
|
||||
A->getKind() <= attr::LastStmtAttr;
|
||||
}
|
||||
};
|
||||
|
||||
class InheritableAttr : public Attr {
|
||||
protected:
|
||||
InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
@ -129,7 +143,8 @@ class InheritableAttr : public Attr {
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() <= attr::LAST_INHERITABLE;
|
||||
return A->getKind() >= attr::FirstInheritableAttr &&
|
||||
A->getKind() <= attr::LastInheritableAttr;
|
||||
}
|
||||
};
|
||||
|
||||
@ -143,12 +158,41 @@ class InheritableParamAttr : public InheritableAttr {
|
||||
public:
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
// Relies on relative order of enum emission with respect to MS inheritance
|
||||
// attrs.
|
||||
return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
|
||||
return A->getKind() >= attr::FirstInheritableParamAttr &&
|
||||
A->getKind() <= attr::LastInheritableParamAttr;
|
||||
}
|
||||
};
|
||||
|
||||
/// A parameter attribute which changes the argument-passing ABI rule
|
||||
/// for the parameter.
|
||||
class ParameterABIAttr : public InheritableParamAttr {
|
||||
protected:
|
||||
ParameterABIAttr(attr::Kind AK, SourceRange R,
|
||||
unsigned SpellingListIndex, bool IsLateParsed,
|
||||
bool DuplicatesAllowed)
|
||||
: InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed,
|
||||
DuplicatesAllowed) {}
|
||||
|
||||
public:
|
||||
ParameterABI getABI() const {
|
||||
switch (getKind()) {
|
||||
case attr::SwiftContext:
|
||||
return ParameterABI::SwiftContext;
|
||||
case attr::SwiftErrorResult:
|
||||
return ParameterABI::SwiftErrorResult;
|
||||
case attr::SwiftIndirectResult:
|
||||
return ParameterABI::SwiftIndirectResult;
|
||||
default:
|
||||
llvm_unreachable("bad parameter ABI attribute kind");
|
||||
}
|
||||
}
|
||||
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() >= attr::FirstParameterABIAttr &&
|
||||
A->getKind() <= attr::LastParameterABIAttr;
|
||||
}
|
||||
};
|
||||
|
||||
#include "clang/AST/Attrs.inc"
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
|
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 @@ class TranslationUnitDecl : public Decl, public DeclContext {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a `#pragma comment` line. Always a child of
|
||||
/// TranslationUnitDecl.
|
||||
class PragmaCommentDecl final
|
||||
: public Decl,
|
||||
private llvm::TrailingObjects<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 @@ class NamedDecl : public Decl {
|
||||
NamedDecl *getUnderlyingDecl() {
|
||||
// Fast-path the common case.
|
||||
if (this->getKind() != UsingShadow &&
|
||||
this->getKind() != ConstructorUsingShadow &&
|
||||
this->getKind() != ObjCCompatibleAlias &&
|
||||
this->getKind() != NamespaceAlias)
|
||||
return this;
|
||||
@ -813,12 +882,15 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
/// variable; see isARCPseudoStrong() for details.
|
||||
unsigned ARCPseudoStrong : 1;
|
||||
|
||||
/// \brief Whether this variable is (C++1z) inline.
|
||||
unsigned IsInline : 1;
|
||||
|
||||
/// \brief Whether this variable has (C++1z) inline explicitly specified.
|
||||
unsigned IsInlineSpecified : 1;
|
||||
|
||||
/// \brief Whether this variable is (C++0x) constexpr.
|
||||
unsigned IsConstexpr : 1;
|
||||
|
||||
/// \brief Whether this variable is a (C++ Concepts TS) concept.
|
||||
unsigned IsConcept : 1;
|
||||
|
||||
/// \brief Whether this variable is the implicit variable for a lambda
|
||||
/// init-capture.
|
||||
unsigned IsInitCapture : 1;
|
||||
@ -1037,9 +1109,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
/// definition of a static data member.
|
||||
bool isOutOfLine() const override;
|
||||
|
||||
/// \brief If this is a static data member, find its out-of-line definition.
|
||||
VarDecl *getOutOfLineDefinition();
|
||||
|
||||
/// isFileVarDecl - Returns true for file scoped variable declaration.
|
||||
bool isFileVarDecl() const {
|
||||
Kind K = getKind();
|
||||
@ -1185,6 +1254,24 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
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 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
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 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
return isDefined(Definition);
|
||||
}
|
||||
|
||||
/// \brief Get the definition for this declaration.
|
||||
FunctionDecl *getDefinition() {
|
||||
const FunctionDecl *Definition;
|
||||
if (isDefined(Definition))
|
||||
return const_cast<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 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
|
||||
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 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
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 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
unsigned getMinRequiredArguments() const;
|
||||
|
||||
QualType getReturnType() const {
|
||||
assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
|
||||
return getType()->getAs<FunctionType>()->getReturnType();
|
||||
}
|
||||
|
||||
@ -1964,15 +2043,20 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
|
||||
/// \brief Determine the type of an expression that calls this function.
|
||||
QualType getCallResultType() const {
|
||||
assert(getType()->getAs<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 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
/// 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 @@ class TagDecl
|
||||
/// IsCompleteDefinition - True if this is a definition ("struct foo
|
||||
/// {};"), false if it is a declaration ("struct foo;"). It is not
|
||||
/// a definition until the definition has been fully processed.
|
||||
bool IsCompleteDefinition : 1;
|
||||
unsigned IsCompleteDefinition : 1;
|
||||
|
||||
protected:
|
||||
/// IsBeingDefined - True if this is currently being defined.
|
||||
bool IsBeingDefined : 1;
|
||||
unsigned IsBeingDefined : 1;
|
||||
|
||||
private:
|
||||
/// IsEmbeddedInDeclarator - True if this tag declaration is
|
||||
/// "embedded" (i.e., defined or declared for the very first time)
|
||||
/// in the syntax of a declarator.
|
||||
bool IsEmbeddedInDeclarator : 1;
|
||||
unsigned IsEmbeddedInDeclarator : 1;
|
||||
|
||||
/// \brief True if this tag is free standing, e.g. "struct foo;".
|
||||
bool IsFreeStanding : 1;
|
||||
unsigned IsFreeStanding : 1;
|
||||
|
||||
protected:
|
||||
// These are used by (and only defined for) EnumDecl.
|
||||
@ -2677,28 +2760,28 @@ class TagDecl
|
||||
|
||||
/// IsScoped - True if this tag declaration is a scoped enumeration. Only
|
||||
/// possible in C++11 mode.
|
||||
bool IsScoped : 1;
|
||||
unsigned IsScoped : 1;
|
||||
/// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
|
||||
/// then this is true if the scoped enum was declared using the class
|
||||
/// tag, false if it was declared with the struct tag. No meaning is
|
||||
/// associated if this tag declaration is not a scoped enum.
|
||||
bool IsScopedUsingClassTag : 1;
|
||||
unsigned IsScopedUsingClassTag : 1;
|
||||
|
||||
/// IsFixed - True if this is an enumeration with fixed underlying type. Only
|
||||
/// possible in C++11, Microsoft extensions, or Objective C mode.
|
||||
bool IsFixed : 1;
|
||||
unsigned IsFixed : 1;
|
||||
|
||||
/// \brief Indicates whether it is possible for declarations of this kind
|
||||
/// to have an out-of-date definition.
|
||||
///
|
||||
/// This option is only enabled when modules are enabled.
|
||||
bool MayHaveOutOfDateDef : 1;
|
||||
unsigned MayHaveOutOfDateDef : 1;
|
||||
|
||||
/// Has the full definition of this type been required by a use somewhere in
|
||||
/// the TU.
|
||||
bool IsCompleteDefinitionRequired : 1;
|
||||
unsigned IsCompleteDefinitionRequired : 1;
|
||||
private:
|
||||
SourceLocation RBraceLoc;
|
||||
SourceRange BraceRange;
|
||||
|
||||
// A struct representing syntactic qualifier info,
|
||||
// to be used for the (uncommon) case of out-of-line declarations.
|
||||
@ -2760,8 +2843,8 @@ class TagDecl
|
||||
using redeclarable_base::getMostRecentDecl;
|
||||
using redeclarable_base::isFirstDecl;
|
||||
|
||||
SourceLocation getRBraceLoc() const { return RBraceLoc; }
|
||||
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
|
||||
SourceRange getBraceRange() const { return BraceRange; }
|
||||
void setBraceRange(SourceRange R) { BraceRange = R; }
|
||||
|
||||
/// getInnerLocStart - Return SourceLocation representing start of source
|
||||
/// range ignoring outer template declarations.
|
||||
@ -3122,6 +3205,10 @@ class EnumDecl : public TagDecl {
|
||||
return isCompleteDefinition() || isFixed();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the enum definition from which this enumeration could
|
||||
/// be instantiated, if it is an instantiation (rather than a non-template).
|
||||
EnumDecl *getTemplateInstantiationPattern() const;
|
||||
|
||||
/// \brief Returns the enumeration (declared within the template)
|
||||
/// from which this enumeration type was instantiated, or NULL if
|
||||
/// this enumeration was not instantiated from any template.
|
||||
@ -3452,35 +3539,23 @@ class BlockDecl : public Decl, public DeclContext {
|
||||
void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
|
||||
TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
|
||||
|
||||
// Iterator access to formal parameters.
|
||||
unsigned param_size() const { return getNumParams(); }
|
||||
typedef ParmVarDecl **param_iterator;
|
||||
typedef ParmVarDecl * const *param_const_iterator;
|
||||
typedef llvm::iterator_range<param_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 @@ class BlockDecl : public Decl, public DeclContext {
|
||||
/// Does not include an entry for 'this'.
|
||||
unsigned getNumCaptures() const { return NumCaptures; }
|
||||
|
||||
typedef const Capture *capture_iterator;
|
||||
typedef const Capture *capture_const_iterator;
|
||||
typedef llvm::iterator_range<capture_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 @@ class CapturedDecl final
|
||||
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 @@ class CapturedDecl final
|
||||
/// \brief Retrieve an iterator one past the last parameter decl.
|
||||
param_iterator param_end() const { return getParams() + NumParams; }
|
||||
|
||||
/// \brief Retrieve an iterator range for the parameter declarations.
|
||||
param_range params() const { return param_range(param_begin(), param_end()); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == Captured; }
|
||||
|
@ -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 @@ class Decl {
|
||||
/// has been declared outside any function. These act mostly like
|
||||
/// invisible friend declarations, but are also visible to unqualified
|
||||
/// lookup within the scope of the declaring function.
|
||||
IDNS_LocalExtern = 0x0800
|
||||
IDNS_LocalExtern = 0x0800,
|
||||
|
||||
/// This declaration is an OpenMP user defined reduction construction.
|
||||
IDNS_OMPReduction = 0x1000
|
||||
};
|
||||
|
||||
/// ObjCDeclQualifier - 'Qualifiers' written next to the return and
|
||||
@ -256,7 +257,7 @@ class Decl {
|
||||
SourceLocation Loc;
|
||||
|
||||
/// DeclKind - This indicates which class this is.
|
||||
unsigned DeclKind : 8;
|
||||
unsigned DeclKind : 7;
|
||||
|
||||
/// InvalidDecl - This indicates a semantic error occurred.
|
||||
unsigned InvalidDecl : 1;
|
||||
@ -296,7 +297,7 @@ class Decl {
|
||||
unsigned Hidden : 1;
|
||||
|
||||
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
|
||||
unsigned IdentifierNamespace : 12;
|
||||
unsigned IdentifierNamespace : 13;
|
||||
|
||||
/// \brief If 0, we have not computed the linkage of this declaration.
|
||||
/// Otherwise, it is the linkage + 1.
|
||||
@ -514,8 +515,8 @@ class Decl {
|
||||
bool isImplicit() const { return Implicit; }
|
||||
void setImplicit(bool I = true) { Implicit = I; }
|
||||
|
||||
/// \brief Whether this declaration was used, meaning that a definition
|
||||
/// is required.
|
||||
/// \brief Whether *any* (re-)declaration of the entity was used, meaning that
|
||||
/// a definition is required.
|
||||
///
|
||||
/// \param CheckUsedAttr When true, also consider the "used" attribute
|
||||
/// (in addition to the "used" bit set by \c setUsed()) when determining
|
||||
@ -525,7 +526,8 @@ class Decl {
|
||||
/// \brief Set whether the declaration is used, in the sense of odr-use.
|
||||
///
|
||||
/// This should only be used immediately after creating a declaration.
|
||||
void setIsUsed() { Used = true; }
|
||||
/// It intentionally doesn't notify any listeners.
|
||||
void setIsUsed() { getCanonicalDecl()->Used = true; }
|
||||
|
||||
/// \brief Mark the declaration used, in the sense of odr-use.
|
||||
///
|
||||
@ -564,6 +566,13 @@ class Decl {
|
||||
return NextInContextAndBits.getInt() & ModulePrivateFlag;
|
||||
}
|
||||
|
||||
/// Return true if this declaration has an attribute which acts as
|
||||
/// definition of the entity, such as 'alias' or 'ifunc'.
|
||||
bool hasDefiningAttr() const;
|
||||
|
||||
/// Return this declaration's defining attribute if it has one.
|
||||
const Attr *getDefiningAttr() const;
|
||||
|
||||
protected:
|
||||
/// \brief Specify whether this declaration was marked as being private
|
||||
/// to the module in which it was defined.
|
||||
@ -895,6 +904,10 @@ class Decl {
|
||||
DeclKind == FunctionTemplate;
|
||||
}
|
||||
|
||||
/// \brief If this is a declaration that describes some template, this
|
||||
/// method returns that template declaration.
|
||||
TemplateDecl *getDescribedTemplate() const;
|
||||
|
||||
/// \brief Returns the function itself, or the templated function if this is a
|
||||
/// function template.
|
||||
FunctionDecl *getAsFunction() LLVM_READONLY;
|
||||
@ -1117,6 +1130,7 @@ class DeclContextLookupResult {
|
||||
/// ObjCContainerDecl
|
||||
/// LinkageSpecDecl
|
||||
/// BlockDecl
|
||||
/// OMPDeclareReductionDecl
|
||||
///
|
||||
class DeclContext {
|
||||
/// DeclKind - This indicates which class this is.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LLVM_CLANG_AST_DECLCXX_H
|
||||
#define LLVM_CLANG_AST_DECLCXX_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTUnresolvedSet.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
@ -29,6 +30,7 @@ namespace clang {
|
||||
|
||||
class ClassTemplateDecl;
|
||||
class ClassTemplateSpecializationDecl;
|
||||
class ConstructorUsingShadowDecl;
|
||||
class CXXBasePath;
|
||||
class CXXBasePaths;
|
||||
class CXXConstructorDecl;
|
||||
@ -165,13 +167,13 @@ class CXXBaseSpecifier {
|
||||
SourceLocation EllipsisLoc;
|
||||
|
||||
/// \brief Whether this is a virtual base class or not.
|
||||
bool Virtual : 1;
|
||||
unsigned Virtual : 1;
|
||||
|
||||
/// \brief Whether this is the base of a class (true) or of a struct (false).
|
||||
///
|
||||
/// This determines the mapping from the access specifier as written in the
|
||||
/// source code to the access specifier used for semantic analysis.
|
||||
bool BaseOfClass : 1;
|
||||
unsigned BaseOfClass : 1;
|
||||
|
||||
/// \brief Access specifier as written in the source code (may be AS_none).
|
||||
///
|
||||
@ -181,7 +183,7 @@ class CXXBaseSpecifier {
|
||||
|
||||
/// \brief Whether the class contains a using declaration
|
||||
/// to inherit the named class's constructors.
|
||||
bool InheritConstructors : 1;
|
||||
unsigned InheritConstructors : 1;
|
||||
|
||||
/// \brief The type of the base class.
|
||||
///
|
||||
@ -257,30 +259,6 @@ class CXXBaseSpecifier {
|
||||
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
|
||||
};
|
||||
|
||||
/// \brief A lazy pointer to the definition data for a declaration.
|
||||
/// FIXME: This is a little CXXRecordDecl-specific that the moment.
|
||||
template<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 @@ class CXXRecordDecl : public RecordDecl {
|
||||
}
|
||||
|
||||
CXXRecordDecl *getDefinition() const {
|
||||
auto *DD = DefinitionData.get();
|
||||
// We only need an update if we don't already know which
|
||||
// declaration is the definition.
|
||||
auto *DD = DefinitionData ? DefinitionData : dataPtr();
|
||||
return DD ? DD->Definition : nullptr;
|
||||
}
|
||||
|
||||
bool hasDefinition() const { return DefinitionData.get(); }
|
||||
bool hasDefinition() const { return DefinitionData || dataPtr(); }
|
||||
|
||||
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
@ -1021,7 +1026,7 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief Determine whether this class describes a lambda function object.
|
||||
bool isLambda() const {
|
||||
// An update record can't turn a non-lambda into a lambda.
|
||||
auto *DD = DefinitionData.getNotUpdated();
|
||||
auto *DD = DefinitionData;
|
||||
return DD && DD->IsLambda;
|
||||
}
|
||||
|
||||
@ -1136,9 +1141,10 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief Determine whether this is an empty class in the sense of
|
||||
/// (C++11 [meta.unary.prop]).
|
||||
///
|
||||
/// A non-union class is empty iff it has a virtual function, virtual base,
|
||||
/// data member (other than 0-width bit-field) or inherits from a non-empty
|
||||
/// class.
|
||||
/// The CXXRecordDecl is a class type, but not a union type,
|
||||
/// with no non-static data members other than bit-fields of length 0,
|
||||
/// no virtual member functions, no virtual base classes,
|
||||
/// and no base class B for which is_empty<B>::value is false.
|
||||
///
|
||||
/// \note This does NOT include a check for union-ness.
|
||||
bool isEmpty() const { return data().Empty; }
|
||||
@ -1270,6 +1276,14 @@ class CXXRecordDecl : public RecordDecl {
|
||||
return !(data().HasTrivialSpecialMembers & SMF_Destructor);
|
||||
}
|
||||
|
||||
/// \brief Determine whether declaring a const variable with this type is ok
|
||||
/// per core issue 253.
|
||||
bool allowConstDefaultInit() const {
|
||||
return !data().HasUninitializedFields ||
|
||||
!(data().HasDefaultedDefaultConstructor ||
|
||||
needsImplicitDefaultConstructor());
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a destructor which has no
|
||||
/// semantic effect.
|
||||
///
|
||||
@ -1285,6 +1299,18 @@ class CXXRecordDecl : public RecordDecl {
|
||||
return data().HasNonLiteralTypeFieldsOrBases;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a using-declaration that names
|
||||
/// a user-declared base class constructor.
|
||||
bool hasInheritedConstructor() const {
|
||||
return data().HasInheritedConstructor;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a using-declaration that names
|
||||
/// a base class assignment operator.
|
||||
bool hasInheritedAssignment() const {
|
||||
return data().HasInheritedAssignment;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class is considered trivially copyable per
|
||||
/// (C++11 [class]p6).
|
||||
bool isTriviallyCopyable() const;
|
||||
@ -1554,6 +1580,14 @@ class CXXRecordDecl : public RecordDecl {
|
||||
static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path, DeclarationName Name);
|
||||
|
||||
/// \brief Base-class lookup callback that determines whether there exists
|
||||
/// an OpenMP declare reduction member with the given name.
|
||||
///
|
||||
/// This callback can be used with \c lookupInBases() to find members
|
||||
/// of the given name within a C++ class hierarchy.
|
||||
static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path, DeclarationName Name);
|
||||
|
||||
/// \brief Base-class lookup callback that determines whether there exists
|
||||
/// a member with the given name that can be used in a nested-name-specifier.
|
||||
///
|
||||
@ -1690,6 +1724,7 @@ class CXXRecordDecl : public RecordDecl {
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTRecordWriter;
|
||||
friend class ASTReader;
|
||||
friend class ASTWriter;
|
||||
};
|
||||
@ -1795,6 +1830,8 @@ class CXXMethodDecl : public FunctionDecl {
|
||||
method_iterator begin_overridden_methods() const;
|
||||
method_iterator end_overridden_methods() const;
|
||||
unsigned size_overridden_methods() const;
|
||||
typedef ASTContext::overridden_method_range overridden_method_range;
|
||||
overridden_method_range overridden_methods() const;
|
||||
|
||||
/// Returns the parent of this method declaration, which
|
||||
/// is the class in which this method is defined.
|
||||
@ -1910,15 +1947,15 @@ class CXXCtorInitializer final
|
||||
|
||||
/// \brief If the initializee is a type, whether that type makes this
|
||||
/// a delegating initialization.
|
||||
bool IsDelegating : 1;
|
||||
unsigned IsDelegating : 1;
|
||||
|
||||
/// \brief If the initializer is a base initializer, this keeps track
|
||||
/// of whether the base is virtual or not.
|
||||
bool IsVirtual : 1;
|
||||
unsigned IsVirtual : 1;
|
||||
|
||||
/// \brief Whether or not the initializer is explicitly written
|
||||
/// in the sources.
|
||||
bool IsWritten : 1;
|
||||
unsigned IsWritten : 1;
|
||||
|
||||
/// If IsWritten is true, then this number keeps track of the textual order
|
||||
/// of this initializer in the original sources, counting from 0; otherwise,
|
||||
@ -2109,8 +2146,7 @@ class CXXCtorInitializer final
|
||||
assert(I < getNumArrayIndices() && "Out of bounds member array index");
|
||||
getTrailingObjects<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 @@ class CXXCtorInitializer final
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
/// Description of a constructor that was inherited from a base class.
|
||||
class InheritedConstructor {
|
||||
ConstructorUsingShadowDecl *Shadow;
|
||||
CXXConstructorDecl *BaseCtor;
|
||||
|
||||
public:
|
||||
InheritedConstructor() : Shadow(), BaseCtor() {}
|
||||
InheritedConstructor(ConstructorUsingShadowDecl *Shadow,
|
||||
CXXConstructorDecl *BaseCtor)
|
||||
: Shadow(Shadow), BaseCtor(BaseCtor) {}
|
||||
|
||||
explicit operator bool() const { return Shadow; }
|
||||
|
||||
ConstructorUsingShadowDecl *getShadowDecl() const { return Shadow; }
|
||||
CXXConstructorDecl *getConstructor() const { return BaseCtor; }
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ constructor within a class.
|
||||
///
|
||||
/// For example:
|
||||
@ -2131,40 +2184,51 @@ class CXXCtorInitializer final
|
||||
/// explicit X(int); // represented by a CXXConstructorDecl.
|
||||
/// };
|
||||
/// \endcode
|
||||
class CXXConstructorDecl : public CXXMethodDecl {
|
||||
class CXXConstructorDecl final
|
||||
: public CXXMethodDecl,
|
||||
private llvm::TrailingObjects<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 @@ class CXXConstructorDecl : public CXXMethodDecl {
|
||||
/// an object.
|
||||
bool isSpecializationCopyingObject() const;
|
||||
|
||||
/// \brief Get the constructor that this inheriting constructor is based on.
|
||||
const CXXConstructorDecl *getInheritedConstructor() const;
|
||||
/// \brief Determine whether this is an implicit constructor synthesized to
|
||||
/// model a call to a constructor inherited from a base class.
|
||||
bool isInheritingConstructor() const { return IsInheritingConstructor; }
|
||||
|
||||
/// \brief Set the constructor that this inheriting constructor is based on.
|
||||
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
|
||||
/// \brief Get the constructor that this inheriting constructor is based on.
|
||||
InheritedConstructor getInheritedConstructor() const {
|
||||
return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>()
|
||||
: InheritedConstructor();
|
||||
}
|
||||
|
||||
CXXConstructorDecl *getCanonicalDecl() override {
|
||||
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
|
||||
@ -2330,6 +2398,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ destructor within a class.
|
||||
@ -2774,18 +2843,6 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<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 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
|
||||
using redeclarable_base::redecls;
|
||||
using redeclarable_base::getPreviousDecl;
|
||||
using redeclarable_base::getMostRecentDecl;
|
||||
using redeclarable_base::isFirstDecl;
|
||||
|
||||
UsingShadowDecl *getCanonicalDecl() override {
|
||||
return getFirstDecl();
|
||||
@ -2843,7 +2906,125 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
|
||||
}
|
||||
|
||||
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 @@ class FriendDecl final
|
||||
/// True if this 'friend' declaration is unsupported. Eventually we
|
||||
/// will support every possible friend declaration, but for now we
|
||||
/// silently ignore some and set this flag to authorize all access.
|
||||
bool UnsupportedFriend : 1;
|
||||
unsigned UnsupportedFriend : 1;
|
||||
|
||||
// The number of "outer" template parameter lists in non-templatic
|
||||
// (currently unsupported) friend type declarations, such as
|
||||
|
@ -351,11 +351,6 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
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 @@ class ObjCTypeParamList final
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
enum class ObjCPropertyQueryKind : uint8_t {
|
||||
OBJC_PR_query_unknown = 0x00,
|
||||
OBJC_PR_query_instance,
|
||||
OBJC_PR_query_class
|
||||
};
|
||||
|
||||
/// \brief Represents one property declaration in an Objective-C interface.
|
||||
///
|
||||
/// For example:
|
||||
/// \code{.mm}
|
||||
/// \@property (assign, readwrite) int MyProperty;
|
||||
/// \endcode
|
||||
class ObjCPropertyDecl : public NamedDecl {
|
||||
void anchor() override;
|
||||
public:
|
||||
enum PropertyAttributeKind {
|
||||
OBJC_PR_noattr = 0x00,
|
||||
OBJC_PR_readonly = 0x01,
|
||||
OBJC_PR_getter = 0x02,
|
||||
OBJC_PR_assign = 0x04,
|
||||
OBJC_PR_readwrite = 0x08,
|
||||
OBJC_PR_retain = 0x10,
|
||||
OBJC_PR_copy = 0x20,
|
||||
OBJC_PR_nonatomic = 0x40,
|
||||
OBJC_PR_setter = 0x80,
|
||||
OBJC_PR_atomic = 0x100,
|
||||
OBJC_PR_weak = 0x200,
|
||||
OBJC_PR_strong = 0x400,
|
||||
OBJC_PR_unsafe_unretained = 0x800,
|
||||
/// Indicates that the nullability of the type was spelled with a
|
||||
/// property attribute rather than a type qualifier.
|
||||
OBJC_PR_nullability = 0x1000,
|
||||
OBJC_PR_null_resettable = 0x2000,
|
||||
OBJC_PR_class = 0x4000
|
||||
// Adding a property should change NumPropertyAttrsBits
|
||||
};
|
||||
|
||||
enum {
|
||||
/// \brief Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 15
|
||||
};
|
||||
|
||||
enum SetterKind { Assign, Retain, Copy, Weak };
|
||||
enum PropertyControl { None, Required, Optional };
|
||||
private:
|
||||
SourceLocation AtLoc; // location of \@property
|
||||
SourceLocation LParenLoc; // location of '(' starting attribute list or null.
|
||||
QualType DeclType;
|
||||
TypeSourceInfo *DeclTypeSourceInfo;
|
||||
unsigned PropertyAttributes : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
|
||||
// \@required/\@optional
|
||||
unsigned PropertyImplementation : 2;
|
||||
|
||||
Selector GetterName; // getter name of NULL if no getter
|
||||
Selector SetterName; // setter name of NULL if no setter
|
||||
|
||||
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
|
||||
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
|
||||
ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
|
||||
|
||||
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
||||
SourceLocation AtLocation, SourceLocation LParenLocation,
|
||||
QualType T, TypeSourceInfo *TSI,
|
||||
PropertyControl propControl)
|
||||
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
|
||||
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
|
||||
PropertyAttributes(OBJC_PR_noattr),
|
||||
PropertyAttributesAsWritten(OBJC_PR_noattr),
|
||||
PropertyImplementation(propControl),
|
||||
GetterName(Selector()),
|
||||
SetterName(Selector()),
|
||||
GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
|
||||
PropertyIvarDecl(nullptr) {}
|
||||
|
||||
public:
|
||||
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, SourceLocation AtLocation,
|
||||
SourceLocation LParenLocation,
|
||||
QualType T,
|
||||
TypeSourceInfo *TSI,
|
||||
PropertyControl propControl = None);
|
||||
|
||||
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||
|
||||
TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
|
||||
|
||||
QualType getType() const { return DeclType; }
|
||||
|
||||
void setType(QualType T, TypeSourceInfo *TSI) {
|
||||
DeclType = T;
|
||||
DeclTypeSourceInfo = TSI;
|
||||
}
|
||||
|
||||
/// Retrieve the type when this property is used with a specific base object
|
||||
/// type.
|
||||
QualType getUsageType(QualType objectType) const;
|
||||
|
||||
PropertyAttributeKind getPropertyAttributes() const {
|
||||
return PropertyAttributeKind(PropertyAttributes);
|
||||
}
|
||||
void setPropertyAttributes(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributes |= PRVal;
|
||||
}
|
||||
void overwritePropertyAttributes(unsigned PRVal) {
|
||||
PropertyAttributes = PRVal;
|
||||
}
|
||||
|
||||
PropertyAttributeKind getPropertyAttributesAsWritten() const {
|
||||
return PropertyAttributeKind(PropertyAttributesAsWritten);
|
||||
}
|
||||
|
||||
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributesAsWritten = PRVal;
|
||||
}
|
||||
|
||||
// Helper methods for accessing attributes.
|
||||
|
||||
/// isReadOnly - Return true iff the property has a setter.
|
||||
bool isReadOnly() const {
|
||||
return (PropertyAttributes & OBJC_PR_readonly);
|
||||
}
|
||||
|
||||
/// isAtomic - Return true if the property is atomic.
|
||||
bool isAtomic() const {
|
||||
return (PropertyAttributes & OBJC_PR_atomic);
|
||||
}
|
||||
|
||||
/// isRetaining - Return true if the property retains its value.
|
||||
bool isRetaining() const {
|
||||
return (PropertyAttributes &
|
||||
(OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
|
||||
}
|
||||
|
||||
bool isInstanceProperty() const { return !isClassProperty(); }
|
||||
bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
|
||||
ObjCPropertyQueryKind getQueryKind() const {
|
||||
return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
|
||||
ObjCPropertyQueryKind::OBJC_PR_query_instance;
|
||||
}
|
||||
static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) {
|
||||
return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class :
|
||||
ObjCPropertyQueryKind::OBJC_PR_query_instance;
|
||||
}
|
||||
|
||||
/// getSetterKind - Return the method used for doing assignment in
|
||||
/// the property setter. This is only valid if the property has been
|
||||
/// defined to have a setter.
|
||||
SetterKind getSetterKind() const {
|
||||
if (PropertyAttributes & OBJC_PR_strong)
|
||||
return getType()->isBlockPointerType() ? Copy : Retain;
|
||||
if (PropertyAttributes & OBJC_PR_retain)
|
||||
return Retain;
|
||||
if (PropertyAttributes & OBJC_PR_copy)
|
||||
return Copy;
|
||||
if (PropertyAttributes & OBJC_PR_weak)
|
||||
return Weak;
|
||||
return Assign;
|
||||
}
|
||||
|
||||
Selector getGetterName() const { return GetterName; }
|
||||
void setGetterName(Selector Sel) { GetterName = Sel; }
|
||||
|
||||
Selector getSetterName() const { return SetterName; }
|
||||
void setSetterName(Selector Sel) { SetterName = Sel; }
|
||||
|
||||
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
|
||||
void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
|
||||
|
||||
ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
|
||||
void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
|
||||
|
||||
// Related to \@optional/\@required declared in \@protocol
|
||||
void setPropertyImplementation(PropertyControl pc) {
|
||||
PropertyImplementation = pc;
|
||||
}
|
||||
PropertyControl getPropertyImplementation() const {
|
||||
return PropertyControl(PropertyImplementation);
|
||||
}
|
||||
|
||||
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
|
||||
PropertyIvarDecl = Ivar;
|
||||
}
|
||||
ObjCIvarDecl *getPropertyIvarDecl() const {
|
||||
return PropertyIvarDecl;
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(AtLoc, getLocation());
|
||||
}
|
||||
|
||||
/// Get the default name of the synthesized ivar.
|
||||
IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
|
||||
|
||||
/// Lookup a property by name in the specified DeclContext.
|
||||
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
|
||||
const IdentifierInfo *propertyID,
|
||||
ObjCPropertyQueryKind queryKind);
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCProperty; }
|
||||
};
|
||||
|
||||
/// ObjCContainerDecl - Represents a container for method declarations.
|
||||
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
|
||||
/// ObjCProtocolDecl, and ObjCImplDecl.
|
||||
@ -708,7 +913,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||
SourceLocation atStartLoc)
|
||||
: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
|
||||
|
||||
// Iterator access to properties.
|
||||
// Iterator access to instance/class properties.
|
||||
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
|
||||
typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
|
||||
prop_range;
|
||||
@ -721,6 +926,36 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||
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 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
|
||||
|
||||
ObjCPropertyDecl *
|
||||
FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
|
||||
FindPropertyDeclaration(const IdentifierInfo *PropertyId,
|
||||
ObjCPropertyQueryKind QueryKind) const;
|
||||
|
||||
typedef llvm::DenseMap<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 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
}
|
||||
|
||||
ObjCPropertyDecl
|
||||
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
|
||||
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId,
|
||||
ObjCPropertyQueryKind QueryKind) const;
|
||||
|
||||
void collectPropertiesToImplement(PropertyMap &PM,
|
||||
PropertyDeclOrder &PO) const override;
|
||||
@ -1529,8 +1768,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
/// including in all categories except for category passed
|
||||
/// as argument.
|
||||
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
|
||||
const ObjCCategoryDecl *Cat) const {
|
||||
return lookupMethod(Sel, true/*isInstance*/,
|
||||
const ObjCCategoryDecl *Cat,
|
||||
bool IsClassProperty) const {
|
||||
return lookupMethod(Sel, !IsClassProperty/*isInstance*/,
|
||||
false/*shallowCategoryLookup*/,
|
||||
true /* followsSuper */,
|
||||
Cat);
|
||||
@ -2099,7 +2339,8 @@ class ObjCImplDecl : public ObjCContainerDecl {
|
||||
|
||||
void addPropertyImplementation(ObjCPropertyImplDecl *property);
|
||||
|
||||
ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
|
||||
ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId,
|
||||
ObjCPropertyQueryKind queryKind) const;
|
||||
ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
|
||||
|
||||
// Iterator access to properties.
|
||||
@ -2407,197 +2648,6 @@ class ObjCCompatibleAliasDecl : public NamedDecl {
|
||||
|
||||
};
|
||||
|
||||
/// \brief Represents one property declaration in an Objective-C interface.
|
||||
///
|
||||
/// For example:
|
||||
/// \code{.mm}
|
||||
/// \@property (assign, readwrite) int MyProperty;
|
||||
/// \endcode
|
||||
class ObjCPropertyDecl : public NamedDecl {
|
||||
void anchor() override;
|
||||
public:
|
||||
enum PropertyAttributeKind {
|
||||
OBJC_PR_noattr = 0x00,
|
||||
OBJC_PR_readonly = 0x01,
|
||||
OBJC_PR_getter = 0x02,
|
||||
OBJC_PR_assign = 0x04,
|
||||
OBJC_PR_readwrite = 0x08,
|
||||
OBJC_PR_retain = 0x10,
|
||||
OBJC_PR_copy = 0x20,
|
||||
OBJC_PR_nonatomic = 0x40,
|
||||
OBJC_PR_setter = 0x80,
|
||||
OBJC_PR_atomic = 0x100,
|
||||
OBJC_PR_weak = 0x200,
|
||||
OBJC_PR_strong = 0x400,
|
||||
OBJC_PR_unsafe_unretained = 0x800,
|
||||
/// Indicates that the nullability of the type was spelled with a
|
||||
/// property attribute rather than a type qualifier.
|
||||
OBJC_PR_nullability = 0x1000,
|
||||
OBJC_PR_null_resettable = 0x2000
|
||||
// Adding a property should change NumPropertyAttrsBits
|
||||
};
|
||||
|
||||
enum {
|
||||
/// \brief Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 14
|
||||
};
|
||||
|
||||
enum SetterKind { Assign, Retain, Copy, Weak };
|
||||
enum PropertyControl { None, Required, Optional };
|
||||
private:
|
||||
SourceLocation AtLoc; // location of \@property
|
||||
SourceLocation LParenLoc; // location of '(' starting attribute list or null.
|
||||
QualType DeclType;
|
||||
TypeSourceInfo *DeclTypeSourceInfo;
|
||||
unsigned PropertyAttributes : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
|
||||
// \@required/\@optional
|
||||
unsigned PropertyImplementation : 2;
|
||||
|
||||
Selector GetterName; // getter name of NULL if no getter
|
||||
Selector SetterName; // setter name of NULL if no setter
|
||||
|
||||
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
|
||||
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
|
||||
ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
|
||||
|
||||
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
||||
SourceLocation AtLocation, SourceLocation LParenLocation,
|
||||
QualType T, TypeSourceInfo *TSI,
|
||||
PropertyControl propControl)
|
||||
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
|
||||
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
|
||||
PropertyAttributes(OBJC_PR_noattr),
|
||||
PropertyAttributesAsWritten(OBJC_PR_noattr),
|
||||
PropertyImplementation(propControl),
|
||||
GetterName(Selector()),
|
||||
SetterName(Selector()),
|
||||
GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
|
||||
PropertyIvarDecl(nullptr) {}
|
||||
|
||||
public:
|
||||
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, SourceLocation AtLocation,
|
||||
SourceLocation LParenLocation,
|
||||
QualType T,
|
||||
TypeSourceInfo *TSI,
|
||||
PropertyControl propControl = None);
|
||||
|
||||
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||
|
||||
TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
|
||||
|
||||
QualType getType() const { return DeclType; }
|
||||
|
||||
void setType(QualType T, TypeSourceInfo *TSI) {
|
||||
DeclType = T;
|
||||
DeclTypeSourceInfo = TSI;
|
||||
}
|
||||
|
||||
/// Retrieve the type when this property is used with a specific base object
|
||||
/// type.
|
||||
QualType getUsageType(QualType objectType) const;
|
||||
|
||||
PropertyAttributeKind getPropertyAttributes() const {
|
||||
return PropertyAttributeKind(PropertyAttributes);
|
||||
}
|
||||
void setPropertyAttributes(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributes |= PRVal;
|
||||
}
|
||||
void overwritePropertyAttributes(unsigned PRVal) {
|
||||
PropertyAttributes = PRVal;
|
||||
}
|
||||
|
||||
PropertyAttributeKind getPropertyAttributesAsWritten() const {
|
||||
return PropertyAttributeKind(PropertyAttributesAsWritten);
|
||||
}
|
||||
|
||||
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributesAsWritten = PRVal;
|
||||
}
|
||||
|
||||
// Helper methods for accessing attributes.
|
||||
|
||||
/// isReadOnly - Return true iff the property has a setter.
|
||||
bool isReadOnly() const {
|
||||
return (PropertyAttributes & OBJC_PR_readonly);
|
||||
}
|
||||
|
||||
/// isAtomic - Return true if the property is atomic.
|
||||
bool isAtomic() const {
|
||||
return (PropertyAttributes & OBJC_PR_atomic);
|
||||
}
|
||||
|
||||
/// isRetaining - Return true if the property retains its value.
|
||||
bool isRetaining() const {
|
||||
return (PropertyAttributes &
|
||||
(OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
|
||||
}
|
||||
|
||||
/// getSetterKind - Return the method used for doing assignment in
|
||||
/// the property setter. This is only valid if the property has been
|
||||
/// defined to have a setter.
|
||||
SetterKind getSetterKind() const {
|
||||
if (PropertyAttributes & OBJC_PR_strong)
|
||||
return getType()->isBlockPointerType() ? Copy : Retain;
|
||||
if (PropertyAttributes & OBJC_PR_retain)
|
||||
return Retain;
|
||||
if (PropertyAttributes & OBJC_PR_copy)
|
||||
return Copy;
|
||||
if (PropertyAttributes & OBJC_PR_weak)
|
||||
return Weak;
|
||||
return Assign;
|
||||
}
|
||||
|
||||
Selector getGetterName() const { return GetterName; }
|
||||
void setGetterName(Selector Sel) { GetterName = Sel; }
|
||||
|
||||
Selector getSetterName() const { return SetterName; }
|
||||
void setSetterName(Selector Sel) { SetterName = Sel; }
|
||||
|
||||
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
|
||||
void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
|
||||
|
||||
ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
|
||||
void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
|
||||
|
||||
// Related to \@optional/\@required declared in \@protocol
|
||||
void setPropertyImplementation(PropertyControl pc) {
|
||||
PropertyImplementation = pc;
|
||||
}
|
||||
PropertyControl getPropertyImplementation() const {
|
||||
return PropertyControl(PropertyImplementation);
|
||||
}
|
||||
|
||||
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
|
||||
PropertyIvarDecl = Ivar;
|
||||
}
|
||||
ObjCIvarDecl *getPropertyIvarDecl() const {
|
||||
return PropertyIvarDecl;
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(AtLoc, getLocation());
|
||||
}
|
||||
|
||||
/// Get the default name of the synthesized ivar.
|
||||
IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
|
||||
|
||||
/// Lookup a property by name in the specified DeclContext.
|
||||
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
|
||||
const IdentifierInfo *propertyID);
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCProperty; }
|
||||
};
|
||||
|
||||
/// ObjCPropertyImplDecl - Represents implementation declaration of a property
|
||||
/// in a class or category implementation block. For example:
|
||||
/// \@synthesize prop1 = ivar1;
|
||||
|
@ -15,11 +15,14 @@
|
||||
#ifndef LLVM_CLANG_AST_DECLOPENMP_H
|
||||
#define LLVM_CLANG_AST_DECLOPENMP_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
|
||||
namespace clang {
|
||||
class Expr;
|
||||
|
||||
/// \brief This represents '#pragma omp threadprivate ...' directive.
|
||||
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
|
||||
@ -86,6 +89,107 @@ class OMPThreadPrivateDecl final
|
||||
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
/// \brief This represents '#pragma omp declare reduction ...' directive.
|
||||
/// For example, in the following, declared reduction 'foo' for types 'int' and
|
||||
/// 'float':
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
|
||||
/// initializer (omp_priv = 0)
|
||||
/// \endcode
|
||||
///
|
||||
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
|
||||
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
|
||||
private:
|
||||
friend class ASTDeclReader;
|
||||
/// \brief Combiner for declare reduction construct.
|
||||
Expr *Combiner;
|
||||
/// \brief Initializer for declare reduction construct.
|
||||
Expr *Initializer;
|
||||
/// \brief Reference to the previous declare reduction construct in the same
|
||||
/// scope with the same name. Required for proper templates instantiation if
|
||||
/// the declare reduction construct is declared inside compound statement.
|
||||
LazyDeclPtr PrevDeclInScope;
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, QualType Ty,
|
||||
OMPDeclareReductionDecl *PrevDeclInScope)
|
||||
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
|
||||
Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {}
|
||||
|
||||
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
|
||||
PrevDeclInScope = Prev;
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Create declare reduction node.
|
||||
static OMPDeclareReductionDecl *
|
||||
Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
|
||||
/// \brief Create deserialized declare reduction node.
|
||||
static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
||||
/// \brief Get combiner expression of the declare reduction construct.
|
||||
Expr *getCombiner() { return Combiner; }
|
||||
const Expr *getCombiner() const { return Combiner; }
|
||||
/// \brief Set combiner expression for the declare reduction construct.
|
||||
void setCombiner(Expr *E) { Combiner = E; }
|
||||
|
||||
/// \brief Get initializer expression (if specified) of the declare reduction
|
||||
/// construct.
|
||||
Expr *getInitializer() { return Initializer; }
|
||||
const Expr *getInitializer() const { return Initializer; }
|
||||
/// \brief Set initializer expression for the declare reduction construct.
|
||||
void setInitializer(Expr *E) { Initializer = E; }
|
||||
|
||||
/// \brief Get reference to previous declare reduction construct in the same
|
||||
/// scope with the same name.
|
||||
OMPDeclareReductionDecl *getPrevDeclInScope();
|
||||
const OMPDeclareReductionDecl *getPrevDeclInScope() const;
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
|
||||
static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
|
||||
return static_cast<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 @@ class TemplateArgumentList final
|
||||
/// \brief Create a new template argument list that copies the given set of
|
||||
/// template arguments.
|
||||
static TemplateArgumentList *CreateCopy(ASTContext &Context,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
ArrayRef<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 @@ class TemplateDecl : public NamedDecl {
|
||||
}
|
||||
|
||||
/// Get the underlying, templated declaration.
|
||||
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
|
||||
NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
@ -367,20 +365,30 @@ class TemplateDecl : public NamedDecl {
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(TemplateParams->getTemplateLoc(),
|
||||
TemplatedDecl->getSourceRange().getEnd());
|
||||
TemplatedDecl.getPointer()->getSourceRange().getEnd());
|
||||
}
|
||||
|
||||
/// Whether this is a (C++ Concepts TS) function or variable concept.
|
||||
bool isConcept() const { return TemplatedDecl.getInt(); }
|
||||
void setConcept() { TemplatedDecl.setInt(true); }
|
||||
|
||||
protected:
|
||||
NamedDecl *TemplatedDecl;
|
||||
/// \brief The named declaration from which this template was instantiated.
|
||||
/// (or null).
|
||||
///
|
||||
/// The boolean value will be true to indicate that this template
|
||||
/// (function or variable) is a concept.
|
||||
llvm::PointerIntPair<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 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
|
||||
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 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
|
||||
|
||||
/// 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 @@ class NonTypeTemplateParmDecl final
|
||||
static NonTypeTemplateParmDecl *
|
||||
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
const QualType *ExpandedTypes, unsigned NumExpandedTypes,
|
||||
TypeSourceInfo **ExpandedTInfos);
|
||||
QualType T, TypeSourceInfo *TInfo, ArrayRef<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 @@ class TemplateTemplateParmDecl final
|
||||
};
|
||||
|
||||
/// \brief Represents the builtin template declaration which is used to
|
||||
/// implement __make_integer_seq. It serves no real purpose beyond existing as
|
||||
/// a place to hold template parameters.
|
||||
/// implement __make_integer_seq and other builtin templates. It serves
|
||||
/// no real purpose beyond existing as a place to hold template parameters.
|
||||
class BuiltinTemplateDecl : public TemplateDecl {
|
||||
void anchor() override;
|
||||
|
||||
@ -1573,8 +1578,7 @@ class ClassTemplateSpecializationDecl
|
||||
DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
ClassTemplateSpecializationDecl *PrevDecl);
|
||||
|
||||
explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
|
||||
@ -1584,8 +1588,7 @@ class ClassTemplateSpecializationDecl
|
||||
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
const TemplateArgument *Args,
|
||||
unsigned NumArgs,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
ClassTemplateSpecializationDecl *PrevDecl);
|
||||
static ClassTemplateSpecializationDecl *
|
||||
CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
@ -1762,8 +1765,8 @@ class ClassTemplateSpecializationDecl
|
||||
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 @@ class ClassTemplatePartialSpecializationDecl
|
||||
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 @@ class ClassTemplatePartialSpecializationDecl
|
||||
cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
|
||||
return First->InstantiatedFromMember.getPointer();
|
||||
}
|
||||
ClassTemplatePartialSpecializationDecl *
|
||||
getInstantiatedFromMemberTemplate() const {
|
||||
return getInstantiatedFromMember();
|
||||
}
|
||||
|
||||
void setInstantiatedFromMember(
|
||||
ClassTemplatePartialSpecializationDecl *PartialSpec) {
|
||||
@ -1982,7 +1987,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
|
||||
|
||||
/// \brief Get the underlying class declarations of the template.
|
||||
CXXRecordDecl *getTemplatedDecl() const {
|
||||
return static_cast<CXXRecordDecl *>(TemplatedDecl);
|
||||
return static_cast<CXXRecordDecl *>(TemplatedDecl.getPointer());
|
||||
}
|
||||
|
||||
/// \brief Returns whether this template declaration defines the primary
|
||||
@ -2154,18 +2159,11 @@ class FriendTemplateDecl : public Decl {
|
||||
// Location of the 'friend' specifier.
|
||||
SourceLocation FriendLoc;
|
||||
|
||||
|
||||
FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
|
||||
unsigned NParams,
|
||||
TemplateParameterList **Params,
|
||||
FriendUnion Friend,
|
||||
SourceLocation FriendLoc)
|
||||
: Decl(Decl::FriendTemplate, DC, Loc),
|
||||
NumParams(NParams),
|
||||
Params(Params),
|
||||
Friend(Friend),
|
||||
FriendLoc(FriendLoc)
|
||||
{}
|
||||
MutableArrayRef<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 @@ class FriendTemplateDecl : public Decl {
|
||||
{}
|
||||
|
||||
public:
|
||||
static FriendTemplateDecl *Create(ASTContext &Context,
|
||||
DeclContext *DC, SourceLocation Loc,
|
||||
unsigned NParams,
|
||||
TemplateParameterList **Params,
|
||||
FriendUnion Friend,
|
||||
SourceLocation FriendLoc);
|
||||
static FriendTemplateDecl *
|
||||
Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
|
||||
MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend,
|
||||
SourceLocation FriendLoc);
|
||||
|
||||
static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
@ -2245,7 +2241,7 @@ class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
|
||||
public:
|
||||
/// Get the underlying function declaration of the template.
|
||||
TypeAliasDecl *getTemplatedDecl() const {
|
||||
return static_cast<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 @@ class ClassScopeFunctionSpecializationDecl : public Decl {
|
||||
bool HasExplicitTemplateArgs,
|
||||
TemplateArgumentListInfo TemplateArgs) {
|
||||
return new (C, DC) ClassScopeFunctionSpecializationDecl(
|
||||
DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
|
||||
DC, Loc, FD, HasExplicitTemplateArgs, std::move(TemplateArgs));
|
||||
}
|
||||
|
||||
static ClassScopeFunctionSpecializationDecl *
|
||||
@ -2428,8 +2424,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
VarTemplateDecl *SpecializedTemplate,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
StorageClass S, const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
StorageClass S,
|
||||
ArrayRef<TemplateArgument> Args);
|
||||
|
||||
explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
|
||||
|
||||
@ -2437,8 +2433,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
|
||||
static VarTemplateSpecializationDecl *
|
||||
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
|
||||
TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
TypeSourceInfo *TInfo, StorageClass S,
|
||||
ArrayRef<TemplateArgument> Args);
|
||||
static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
||||
@ -2502,17 +2498,11 @@ class VarTemplateSpecializationDecl : public VarDecl,
|
||||
/// 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 @@ class VarTemplateSpecializationDecl : public VarDecl,
|
||||
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 @@ class VarTemplatePartialSpecializationDecl
|
||||
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T,
|
||||
TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
|
||||
unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
|
||||
TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos);
|
||||
|
||||
static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
@ -2808,7 +2798,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
|
||||
|
||||
/// \brief Get the underlying variable declarations of the template.
|
||||
VarDecl *getTemplatedDecl() const {
|
||||
return static_cast<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 @@ class DeclarationName {
|
||||
}
|
||||
|
||||
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 @@ class Expr : public Stmt {
|
||||
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
|
||||
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
|
||||
|
||||
/// EvaluateAsFloat - Return true if this is a constant which we can fold and
|
||||
/// convert to a floating point value, using any crazy technique that we
|
||||
/// want to.
|
||||
bool
|
||||
EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,
|
||||
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
|
||||
|
||||
/// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
|
||||
/// constant folded without side-effects, but discard the result.
|
||||
bool isEvaluatable(const ASTContext &Ctx,
|
||||
@ -847,10 +855,12 @@ class OpaqueValueExpr : public Expr {
|
||||
ExprObjectKind OK = OK_Ordinary,
|
||||
Expr *SourceExpr = nullptr)
|
||||
: Expr(OpaqueValueExprClass, T, VK, OK,
|
||||
T->isDependentType(),
|
||||
T->isDependentType() ||
|
||||
(SourceExpr && SourceExpr->isTypeDependent()),
|
||||
T->isDependentType() ||
|
||||
(SourceExpr && SourceExpr->isValueDependent()),
|
||||
T->isInstantiationDependentType(),
|
||||
T->isInstantiationDependentType() ||
|
||||
(SourceExpr && SourceExpr->isInstantiationDependent()),
|
||||
false),
|
||||
SourceExpr(SourceExpr), Loc(Loc) {
|
||||
}
|
||||
@ -1110,6 +1120,10 @@ class DeclRefExpr final
|
||||
return getTrailingObjects<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 @@ class MemberExpr final
|
||||
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 @@ class DesignatedInitExpr final
|
||||
|
||||
/// Whether this designated initializer used the GNU deprecated
|
||||
/// syntax rather than the C99 '=' syntax.
|
||||
bool GNUSyntax : 1;
|
||||
unsigned GNUSyntax : 1;
|
||||
|
||||
/// The number of designators in this initializer expression.
|
||||
unsigned NumDesignators : 15;
|
||||
@ -3956,11 +3978,10 @@ class DesignatedInitExpr final
|
||||
/// expression.
|
||||
Designator *Designators;
|
||||
|
||||
|
||||
DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators,
|
||||
const Designator *Designators,
|
||||
DesignatedInitExpr(const ASTContext &C, QualType Ty,
|
||||
llvm::ArrayRef<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 @@ class DesignatedInitExpr final
|
||||
};
|
||||
|
||||
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 @@ class DesignatedInitExpr final
|
||||
unsigned size() const { return NumDesignators; }
|
||||
|
||||
// Iterator access to the designators.
|
||||
typedef Designator *designators_iterator;
|
||||
designators_iterator designators_begin() { return Designators; }
|
||||
designators_iterator designators_end() {
|
||||
return Designators + NumDesignators;
|
||||
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 @@ class AtomicExpr : public Expr {
|
||||
BI_First = 0
|
||||
};
|
||||
|
||||
// The ABI values for various atomic memory orderings.
|
||||
enum AtomicOrderingKind {
|
||||
AO_ABI_memory_order_relaxed = 0,
|
||||
AO_ABI_memory_order_consume = 1,
|
||||
AO_ABI_memory_order_acquire = 2,
|
||||
AO_ABI_memory_order_release = 3,
|
||||
AO_ABI_memory_order_acq_rel = 4,
|
||||
AO_ABI_memory_order_seq_cst = 5
|
||||
};
|
||||
|
||||
private:
|
||||
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
|
||||
Stmt* SubExprs[END_EXPR];
|
||||
@ -4882,9 +4859,12 @@ class AtomicExpr : public Expr {
|
||||
}
|
||||
|
||||
AtomicOp getOp() const { return Op; }
|
||||
unsigned getNumSubExprs() { return NumSubExprs; }
|
||||
unsigned getNumSubExprs() const { return NumSubExprs; }
|
||||
|
||||
Expr **getSubExprs() { return reinterpret_cast<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 @@ class CXXOperatorCallExpr : public CallExpr {
|
||||
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 @@ class CXXMemberCallExpr : public CallExpr {
|
||||
/// FIXME: Returns 0 for member pointer call exprs.
|
||||
CXXRecordDecl *getRecordDecl() const;
|
||||
|
||||
SourceLocation getExprLoc() const LLVM_READONLY {
|
||||
SourceLocation CLoc = getCallee()->getExprLoc();
|
||||
if (CLoc.isValid())
|
||||
return CLoc;
|
||||
|
||||
return getLocStart();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXMemberCallExprClass;
|
||||
}
|
||||
@ -160,9 +165,7 @@ class CUDAKernelCallExpr : public CallExpr {
|
||||
CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
|
||||
ArrayRef<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 @@ class CUDAKernelCallExpr : public CallExpr {
|
||||
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 @@ class UserDefinedLiteral : public CallExpr {
|
||||
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 @@ class MSPropertySubscriptExpr : public Expr {
|
||||
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 @@ class CXXUuidofExpr : public Expr {
|
||||
Operand = E;
|
||||
}
|
||||
|
||||
StringRef getUuidAsStringRef(ASTContext &Context) const;
|
||||
void setUuidStr(StringRef US) { UuidStr = US; }
|
||||
StringRef getUuidStr() const { return UuidStr; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
|
||||
@ -831,11 +849,6 @@ class CXXUuidofExpr : public Expr {
|
||||
return T->getStmtClass() == CXXUuidofExprClass;
|
||||
}
|
||||
|
||||
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
|
||||
/// a single GUID.
|
||||
static const UuidAttr *GetUuidAttrOfType(QualType QT,
|
||||
bool *HasMultipleGUIDsPtr = nullptr);
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
if (isTypeOperand())
|
||||
@ -1161,18 +1174,21 @@ class CXXConstructExpr : public Expr {
|
||||
SourceLocation Loc;
|
||||
SourceRange ParenOrBraceRange;
|
||||
unsigned NumArgs : 16;
|
||||
bool Elidable : 1;
|
||||
bool HadMultipleCandidates : 1;
|
||||
bool ListInitialization : 1;
|
||||
bool StdInitListInitialization : 1;
|
||||
bool ZeroInitialization : 1;
|
||||
unsigned Elidable : 1;
|
||||
unsigned HadMultipleCandidates : 1;
|
||||
unsigned ListInitialization : 1;
|
||||
unsigned StdInitListInitialization : 1;
|
||||
unsigned ZeroInitialization : 1;
|
||||
unsigned ConstructKind : 2;
|
||||
Stmt **Args;
|
||||
|
||||
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
|
||||
|
||||
protected:
|
||||
CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *d, bool elidable,
|
||||
CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr *> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
@ -1191,15 +1207,12 @@ class CXXConstructExpr : public Expr {
|
||||
public:
|
||||
/// \brief Construct an empty C++ construction expression.
|
||||
explicit CXXConstructExpr(EmptyShell Empty)
|
||||
: Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
|
||||
NumArgs(0), Elidable(false), HadMultipleCandidates(false),
|
||||
ListInitialization(false), ZeroInitialization(false),
|
||||
ConstructKind(0), Args(nullptr)
|
||||
{ }
|
||||
: CXXConstructExpr(CXXConstructExprClass, Empty) {}
|
||||
|
||||
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *D, bool Elidable,
|
||||
CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr *> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
@ -1208,8 +1221,8 @@ class CXXConstructExpr : public Expr {
|
||||
ConstructionKind ConstructKind,
|
||||
SourceRange ParenOrBraceRange);
|
||||
|
||||
/// \brief Get the constructor that this expression will (ultimately) call.
|
||||
CXXConstructorDecl *getConstructor() const { return Constructor; }
|
||||
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
|
||||
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
void setLocation(SourceLocation Loc) { this->Loc = Loc; }
|
||||
@ -1305,6 +1318,73 @@ class CXXConstructExpr : public Expr {
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// \brief Represents a call to an inherited base class constructor from an
|
||||
/// inheriting constructor. This call implicitly forwards the arguments from
|
||||
/// the enclosing context (an inheriting constructor) to the specified inherited
|
||||
/// base class constructor.
|
||||
class CXXInheritedCtorInitExpr : public Expr {
|
||||
private:
|
||||
CXXConstructorDecl *Constructor;
|
||||
|
||||
/// The location of the using declaration.
|
||||
SourceLocation Loc;
|
||||
|
||||
/// Whether this is the construction of a virtual base.
|
||||
unsigned ConstructsVirtualBase : 1;
|
||||
|
||||
/// Whether the constructor is inherited from a virtual base class of the
|
||||
/// class that we construct.
|
||||
unsigned InheritedFromVirtualBase : 1;
|
||||
|
||||
public:
|
||||
/// \brief Construct a C++ inheriting construction expression.
|
||||
CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
|
||||
CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
|
||||
bool InheritedFromVirtualBase)
|
||||
: Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false,
|
||||
false, false, false),
|
||||
Constructor(Ctor), Loc(Loc),
|
||||
ConstructsVirtualBase(ConstructsVirtualBase),
|
||||
InheritedFromVirtualBase(InheritedFromVirtualBase) {
|
||||
assert(!T->isDependentType());
|
||||
}
|
||||
|
||||
/// \brief Construct an empty C++ inheriting construction expression.
|
||||
explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
|
||||
: Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr),
|
||||
ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
|
||||
|
||||
/// \brief Get the constructor that this expression will call.
|
||||
CXXConstructorDecl *getConstructor() const { return Constructor; }
|
||||
|
||||
/// \brief Determine whether this constructor is actually constructing
|
||||
/// a base class (rather than a complete object).
|
||||
bool constructsVBase() const { return ConstructsVirtualBase; }
|
||||
CXXConstructExpr::ConstructionKind getConstructionKind() const {
|
||||
return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase
|
||||
: CXXConstructExpr::CK_NonVirtualBase;
|
||||
}
|
||||
|
||||
/// \brief Determine whether the inherited constructor is inherited from a
|
||||
/// virtual base of the object we construct. If so, we are not responsible
|
||||
/// for calling the inherited constructor (the complete object constructor
|
||||
/// does that), and so we don't need to pass any arguments.
|
||||
bool inheritedFromVBase() const { return InheritedFromVirtualBase; }
|
||||
|
||||
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXInheritedCtorInitExprClass;
|
||||
}
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// \brief Represents an explicit C++ type conversion that uses "functional"
|
||||
/// notation (C++ [expr.type.conv]).
|
||||
///
|
||||
@ -1375,7 +1455,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
|
||||
TypeSourceInfo *Type;
|
||||
|
||||
public:
|
||||
CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
|
||||
CXXTemporaryObjectExpr(const ASTContext &C,
|
||||
CXXConstructorDecl *Cons,
|
||||
TypeSourceInfo *Type,
|
||||
ArrayRef<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 @@ class OverloadExpr : public Expr {
|
||||
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 @@ class DependentScopeDeclRefExpr final
|
||||
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 @@ class ExprWithCleanups final
|
||||
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 @@ class ExprWithCleanups final
|
||||
unsigned numObjects);
|
||||
|
||||
static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
|
||||
bool CleanupsHaveSideEffects,
|
||||
ArrayRef<CleanupObject> objects);
|
||||
|
||||
ArrayRef<CleanupObject> getObjects() const {
|
||||
@ -2884,6 +2975,9 @@ class ExprWithCleanups final
|
||||
|
||||
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 @@ class CXXDependentScopeMemberExpr final
|
||||
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 @@ class ObjCBridgedCastExpr final
|
||||
return T->getStmtClass() == ObjCBridgedCastExprClass;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief A runtime availability query.
|
||||
///
|
||||
/// There are 2 ways to spell this node:
|
||||
/// \code
|
||||
/// @available(macos 10.10, ios 8, *); // Objective-C
|
||||
/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C
|
||||
/// \endcode
|
||||
///
|
||||
/// Note that we only need to keep track of one \c VersionTuple here, which is
|
||||
/// the one that corresponds to the current deployment target. This is meant to
|
||||
/// be used in the condition of an \c if, but it is also usable as top level
|
||||
/// expressions.
|
||||
///
|
||||
class ObjCAvailabilityCheckExpr : public Expr {
|
||||
VersionTuple VersionToCheck;
|
||||
SourceLocation AtLoc, RParen;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
|
||||
SourceLocation RParen, QualType Ty)
|
||||
: Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false,
|
||||
false, false, false),
|
||||
VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {}
|
||||
|
||||
explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
|
||||
: Expr(ObjCAvailabilityCheckExprClass, Shell) {}
|
||||
|
||||
SourceLocation getLocStart() const { return AtLoc; }
|
||||
SourceLocation getLocEnd() const { return RParen; }
|
||||
SourceRange getSourceRange() const { return {AtLoc, RParen}; }
|
||||
|
||||
/// \brief This may be '*', in which case this should fold to true.
|
||||
bool hasVersion() const { return !VersionToCheck.empty(); }
|
||||
VersionTuple getVersion() { return VersionToCheck; }
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -85,7 +85,7 @@ class OMPArraySectionExpr : public Expr {
|
||||
void setBase(Expr *E) { SubExprs[BASE] = E; }
|
||||
|
||||
/// \brief Return original type of the base expression for array section.
|
||||
static QualType getBaseOriginalType(Expr *Base);
|
||||
static QualType getBaseOriginalType(const Expr *Base);
|
||||
|
||||
/// \brief Get lower bound of array section.
|
||||
Expr *getLowerBound() { return cast_or_null<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 @@ class GlobalDecl {
|
||||
GlobalDecl(const BlockDecl *D) { Init(D); }
|
||||
GlobalDecl(const CapturedDecl *D) { Init(D); }
|
||||
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
|
||||
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
|
||||
|
||||
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
|
||||
: Value(D, Type) {}
|
||||
|
@ -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 @@ class LambdaCapture {
|
||||
/// \brief Determine whether this capture handles the C++ \c this
|
||||
/// pointer.
|
||||
bool capturesThis() const {
|
||||
return (DeclAndBits.getPointer() == nullptr) &&
|
||||
!(DeclAndBits.getInt() & Capture_ByCopy);
|
||||
return DeclAndBits.getPointer() == nullptr &&
|
||||
(DeclAndBits.getInt() & Capture_This);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this capture handles a variable.
|
||||
@ -81,8 +93,8 @@ class LambdaCapture {
|
||||
/// \brief Determine whether this captures a variable length array bound
|
||||
/// expression.
|
||||
bool capturesVLAType() const {
|
||||
return (DeclAndBits.getPointer() == nullptr) &&
|
||||
(DeclAndBits.getInt() & Capture_ByCopy);
|
||||
return DeclAndBits.getPointer() == nullptr &&
|
||||
!(DeclAndBits.getInt() & Capture_This);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the declaration of the local variable being
|
||||
@ -91,13 +103,15 @@ class LambdaCapture {
|
||||
/// This operation is only valid if this capture is a variable capture
|
||||
/// (other than a capture of \c this).
|
||||
VarDecl *getCapturedVar() const {
|
||||
assert(capturesVariable() && "No variable available for 'this' capture");
|
||||
return cast<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 @@ class MangleContext {
|
||||
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
|
||||
raw_ostream &Out);
|
||||
|
||||
void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
|
||||
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
|
||||
|
||||
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
|
||||
@ -206,7 +208,8 @@ class MicrosoftMangleContext : public MangleContext {
|
||||
raw_ostream &Out) = 0;
|
||||
|
||||
virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
|
||||
uint32_t NumEntries, raw_ostream &Out) = 0;
|
||||
bool IsUnaligned, uint32_t NumEntries,
|
||||
raw_ostream &Out) = 0;
|
||||
|
||||
virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
|
||||
raw_ostream &Out) = 0;
|
||||
|
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 New Issue
Block a user