Vendor import of clang release_39 branch r276489:

https://llvm.org/svn/llvm-project/cfe/branches/release_39@276489
This commit is contained in:
Dimitry Andric 2016-07-23 20:44:14 +00:00
parent b4348ed0b7
commit 2b6b257f4e
3057 changed files with 291873 additions and 71050 deletions

View File

@ -1,4 +1,4 @@
{
"project_id" : "clang",
"conduit_uri" : "http://reviews.llvm.org/"
"conduit_uri" : "https://reviews.llvm.org/"
}

View File

@ -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
View File

@ -33,3 +33,5 @@ tools/extra
# Sphinx build products
docs/_build
docs/analyzer/_build
# debug info testsuite
test/debuginfo-tests

View File

@ -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()

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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),

View File

@ -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):

View File

@ -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_; };'

View File

@ -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

View 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 "")

View 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)

View File

@ -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

View File

@ -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 "")

View File

@ -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.

View 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()

View 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()

View File

@ -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")

View 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@")

View 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

View File

@ -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)

View File

@ -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).

View File

@ -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

View File

@ -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;
}

View File

@ -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`.

View File

@ -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
======

View File

@ -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

View File

@ -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.

View File

@ -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):

View 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
View 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``.

View File

@ -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
----------------------

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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+

View File

@ -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

View File

@ -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
======================

View File

@ -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
------------

View File

@ -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
View 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

View 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.

View File

@ -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>

View File

@ -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
================

View File

@ -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:
::

View File

@ -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
==========

View File

@ -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."

View File

@ -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.

View File

@ -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.

View File

@ -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!

View File

@ -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.

View File

@ -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

View File

@ -47,7 +47,7 @@ def link_if_exists(m):
except:
doxygen_probes[url] = False
if doxygen_probes[url]:
return r'Matcher&lt<a href="%s">%s</a>&gt;' % (url, name)
return r'Matcher&lt;<a href="%s">%s</a>&gt;' % (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)

View File

@ -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'

View 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");

View 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()

View File

@ -8,3 +8,4 @@ add_subdirectory(analyzer-plugin)
endif()
add_subdirectory(clang-interpreter)
add_subdirectory(PrintFunctionNames)
add_subdirectory(AnnotateFunctions)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
clang_registerCheckers
clang_analyzerAPIVersionString

View File

@ -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

View File

@ -1,4 +0,0 @@
CLANG_LEVEL := ..
DIRS := clang clang-c
include $(CLANG_LEVEL)/Makefile

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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) {}

View File

@ -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,

View File

@ -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.

View File

@ -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.

View File

@ -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; }

View File

@ -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,

View 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

View File

@ -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.

View File

@ -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)

View File

@ -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));
}

View File

@ -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

View File

@ -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; }

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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]); }

View File

@ -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) {}

View File

@ -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).

View File

@ -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;

View File

@ -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, $@) $<

View File

@ -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