Vendor import of clang trunk r300422:

https://llvm.org/svn/llvm-project/cfe/trunk@300422
This commit is contained in:
dim 2017-04-16 16:02:28 +00:00
parent 7789b5ee78
commit d6b76b4ff7
1805 changed files with 98024 additions and 43763 deletions

View File

@ -82,6 +82,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
endif()
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
option(LLVM_INSTALL_TOOLCHAIN_ONLY
"Only include toolchain files in the 'install' target." OFF)
@ -185,6 +186,8 @@ if (LIBXML2_FOUND)
set(CLANG_HAVE_LIBXML 1)
endif()
find_package(Z3 4.5)
include(CheckIncludeFile)
check_include_file(sys/resource.h CLANG_HAVE_RLIMITS)
@ -329,10 +332,6 @@ if (APPLE)
endif()
endif()
configure_file(
${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake
${CLANG_BINARY_DIR}/include/clang/Config/config.h)
include(CMakeParseArguments)
include(AddClang)
@ -368,21 +367,21 @@ 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")
else()
set(ENABLE_CLANG_ARCMT "0")
endif()
option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON)
if (CLANG_ENABLE_STATIC_ANALYZER)
set(ENABLE_CLANG_STATIC_ANALYZER "1")
else()
set(ENABLE_CLANG_STATIC_ANALYZER "0")
option(CLANG_ANALYZER_BUILD_Z3
"Build the static analyzer with the Z3 constraint manager." OFF)
if(NOT CLANG_ENABLE_STATIC_ANALYZER AND (CLANG_ENABLE_ARCMT OR CLANG_ANALYZER_BUILD_Z3))
message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3")
endif()
if (NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT)
message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT")
if(CLANG_ANALYZER_BUILD_Z3)
if(Z3_FOUND)
set(CLANG_ANALYZER_WITH_Z3 1)
else()
message(FATAL_ERROR "Cannot find Z3 header file or shared library")
endif()
endif()
if(CLANG_ENABLE_ARCMT)
@ -419,11 +418,6 @@ add_subdirectory(tools)
add_subdirectory(runtime)
option(CLANG_BUILD_EXAMPLES "Build CLANG example programs by default." OFF)
if (CLANG_BUILD_EXAMPLES)
set(ENABLE_CLANG_EXAMPLES "1")
else()
set(ENABLE_CLANG_EXAMPLES "0")
endif()
add_subdirectory(examples)
if(APPLE)
@ -519,6 +513,10 @@ if (CLANG_ENABLE_BOOTSTRAP)
set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-stamps/)
set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-bins/)
if(BOOTSTRAP_LLVM_ENABLE_LLD)
add_dependencies(clang-bootstrap-deps lld)
endif()
# If the next stage is LTO we need to depend on LTO and possibly lld or LLVMgold
if(BOOTSTRAP_LLVM_ENABLE_LTO OR LLVM_ENABLE_LTO AND NOT LLVM_BUILD_INSTRUMENTED)
if(APPLE)
@ -535,9 +533,7 @@ if (CLANG_ENABLE_BOOTSTRAP)
-DDYLD_LIBRARY_PATH=${LLVM_LIBRARY_OUTPUT_INTDIR})
elseif(NOT WIN32)
add_dependencies(clang-bootstrap-deps llvm-ar llvm-ranlib)
if(BOOTSTRAP_LLVM_ENABLE_LLD)
add_dependencies(clang-bootstrap-deps lld)
elseif(LLVM_BINUTILS_INCDIR)
if(NOT BOOTSTRAP_LLVM_ENABLE_LLD AND LLVM_BINUTILS_INCDIR)
add_dependencies(clang-bootstrap-deps LLVMgold)
endif()
set(LTO_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
@ -700,3 +696,7 @@ endif()
if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION)
add_subdirectory(utils/ClangVisualizers)
endif()
configure_file(
${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake
${CLANG_BINARY_DIR}/include/clang/Config/config.h)

View File

@ -1887,6 +1887,7 @@ def __repr__(self):
TypeKind.OBJCCLASS = TypeKind(28)
TypeKind.OBJCSEL = TypeKind(29)
TypeKind.FLOAT128 = TypeKind(30)
TypeKind.HALF = TypeKind(31)
TypeKind.COMPLEX = TypeKind(100)
TypeKind.POINTER = TypeKind(101)
TypeKind.BLOCKPOINTER = TypeKind(102)

View File

@ -0,0 +1,6 @@
# This file sets up a CMakeCache for Apple-style stage2 ThinLTO bootstrap. It is
# specified by the stage1 build.
set(LLVM_ENABLE_LTO THIN CACHE BOOL "")
include(${CMAKE_CURRENT_LIST_DIR}/Apple-stage2.cmake)

View File

@ -0,0 +1,66 @@
# This file sets up a CMakeCache for the second stage of a Fuchsia toolchain
# build.
set(LLVM_TARGETS_TO_BUILD X86;AArch64 CACHE STRING "")
set(PACKAGE_VENDOR Fuchsia CACHE STRING "")
set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
set(LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD OFF 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(LLVM_ENABLE_LTO ON CACHE BOOL "")
if(NOT APPLE)
set(LLVM_ENABLE_LLD ON CACHE BOOL "")
set(CLANG_DEFAULT_LINKER lld CACHE STRING "")
endif()
if(APPLE)
set(LLDB_CODESIGN_IDENTITY "" CACHE STRING "")
endif()
set(CMAKE_BUILD_TYPE RelWithDebInfo 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(LLVM_BUILTIN_TARGETS "x86_64-fuchsia-none;aarch64-fuchsia-none" CACHE STRING "")
set(BUILTINS_x86_64-fuchsia-none_CMAKE_SYSROOT ${FUCHSIA_SYSROOT} CACHE STRING "")
set(BUILTINS_x86_64-fuchsia-none_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
set(BUILTINS_aarch64-fuchsia-none_CMAKE_SYSROOT ${FUCHSIA_SYSROOT} CACHE STRING "")
set(BUILTINS_aarch64-fuchsia-none_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
# Setup toolchain.
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
set(LLVM_TOOLCHAIN_TOOLS
llvm-ar
llvm-cov
llvm-cxxfilt
llvm-dwarfdump
llvm-dsymutil
llvm-lib
llvm-nm
llvm-objdump
llvm-profdata
llvm-ranlib
llvm-readobj
llvm-size
llvm-symbolizer
CACHE STRING "")
set(LLVM_DISTRIBUTION_COMPONENTS
clang
lld
lldb
liblldb
LTO
clang-format
clang-headers
builtins-x86_64-fuchsia-none
builtins-aarch64-fuchsia-none
runtimes
${LLVM_TOOLCHAIN_TOOLS}
CACHE STRING "")

View File

@ -0,0 +1,50 @@
# This file sets up a CMakeCache for a Fuchsia toolchain build.
set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "")
set(PACKAGE_VENDOR Fuchsia CACHE STRING "")
set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "")
set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "")
set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(CMAKE_BUILD_TYPE Release CACHE STRING "")
set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "")
if(NOT APPLE)
set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "")
endif()
if(APPLE)
set(COMPILER_RT_ENABLE_IOS OFF CACHE BOOL "")
set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "")
set(COMPILER_RT_ENABLE_WATCHOS OFF CACHE BOOL "")
endif()
set(CLANG_BOOTSTRAP_TARGETS
check-all
check-llvm
check-clang
llvm-config
test-suite
test-depends
llvm-test-depends
clang-test-depends
distribution
install-distribution
clang CACHE STRING "")
if(FUCHSIA_SYSROOT)
set(EXTRA_ARGS -DFUCHSIA_SYSROOT=${FUCHSIA_SYSROOT})
endif()
# Setup the bootstrap build.
set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")
set(CLANG_BOOTSTRAP_CMAKE_ARGS
${EXTRA_ARGS}
-C ${CMAKE_CURRENT_LIST_DIR}/Fuchsia-stage2.cmake
CACHE STRING "")

View File

@ -4,17 +4,27 @@
set(CLANG_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/clang)
set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}")
# Keep this in sync with llvm/cmake/CMakeLists.txt!
set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_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_LLVM_CMAKE_DIR "${llvm_cmake_builddir}")
set(CLANG_CONFIG_EXPORTS_FILE "${clang_cmake_builddir}/ClangTargets.cmake")
set(CLANG_CONFIG_INCLUDE_DIRS
"${CLANG_SOURCE_DIR}/include"
"${CLANG_BINARY_DIR}/include"
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in
${clang_cmake_builddir}/ClangConfig.cmake
@ONLY)
set(CLANG_CONFIG_CMAKE_DIR)
set(CLANG_CONFIG_LLVM_CMAKE_DIR)
set(CLANG_CONFIG_EXPORTS_FILE)
# Generate ClangConfig.cmake for the install tree.
@ -29,7 +39,11 @@ foreach(p ${_count})
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_LLVM_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}")
set(CLANG_CONFIG_EXPORTS_FILE "\${CLANG_CMAKE_DIR}/ClangTargets.cmake")
set(CLANG_CONFIG_INCLUDE_DIRS
"\${CLANG_INSTALL_PREFIX}/include"
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/ClangConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake

View File

@ -1,11 +1,13 @@
# This file allows users to call find_package(Clang) and pick up our targets.
find_package(LLVM REQUIRED CONFIG)
@CLANG_CONFIG_CODE@
find_package(LLVM REQUIRED CONFIG
HINTS "@CLANG_CONFIG_LLVM_CMAKE_DIR@")
set(CLANG_EXPORTED_TARGETS "@CLANG_EXPORTS@")
set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@")
set(CLANG_INCLUDE_DIRS "@CLANG_CONFIG_INCLUDE_DIRS@")
# Provide all our library targets to users.
include("@CLANG_CONFIG_EXPORTS_FILE@")

View File

@ -0,0 +1,28 @@
find_path(Z3_INCLUDE_DIR NAMES z3.h
PATH_SUFFIXES libz3 z3
)
find_library(Z3_LIBRARIES NAMES z3 libz3
)
find_program(Z3_EXECUTABLE z3)
if(Z3_INCLUDE_DIR AND Z3_EXECUTABLE)
execute_process (COMMAND ${Z3_EXECUTABLE} -version
OUTPUT_VARIABLE libz3_version_str
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX REPLACE "^Z3 version ([0-9.]+)" "\\1"
Z3_VERSION_STRING "${libz3_version_str}")
unset(libz3_version_str)
endif()
# handle the QUIETLY and REQUIRED arguments and set Z3_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Z3
REQUIRED_VARS Z3_LIBRARIES Z3_INCLUDE_DIR
VERSION_VAR Z3_VERSION_STRING)
mark_as_advanced(Z3_INCLUDE_DIR Z3_LIBRARIES)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -498,12 +498,100 @@ In non-PIE executables the address of an external function (taken from
the main executable) is the address of that functions PLT record in
the main executable. This would break the CFI checks.
Backward-edge CFI for return statements (RCFI)
==============================================
This section is a proposal. As of March 2017 it is not implemented.
Backward-edge control flow (`RET` instructions) can be hijacked
via overwriting the return address (`RA`) on stack.
Various mitigation techniques (e.g. `SafeStack`_, `RFG`_, `Intel CET`_)
try to detect or prevent `RA` corruption on stack.
RCFI enforces the expected control flow in several different ways described below.
RCFI heavily relies on LTO.
Leaf Functions
--------------
If `f()` is a leaf function (i.e. it has no calls
except maybe no-return calls) it can be called using a special calling convention
that stores `RA` in a dedicated register `R` before the `CALL` instruction.
`f()` does not spill `R` and does not use the `RET` instruction,
instead it uses the value in `R` to `JMP` to `RA`.
This flavour of CFI is *precise*, i.e. the function is guaranteed to return
to the point exactly following the call.
An alternative approach is to
copy `RA` from stack to `R` in the first instruction of `f()`,
then `JMP` to `R`.
This approach is simpler to implement (does not require changing the caller)
but weaker (there is a small window when `RA` is actually stored on stack).
Functions called once
---------------------
Suppose `f()` is called in just one place in the program
(assuming we can verify this in LTO mode).
In this case we can replace the `RET` instruction with a `JMP` instruction
with the immediate constant for `RA`.
This will *precisely* enforce the return control flow no matter what is stored on stack.
Another variant is to compare `RA` on stack with the known constant and abort
if they don't match; then `JMP` to the known constant address.
Functions called in a small number of call sites
------------------------------------------------
We may extend the above approach to cases where `f()`
is called more than once (but still a small number of times).
With LTO we know all possible values of `RA` and we check them
one-by-one (or using binary search) against the value on stack.
If the match is found, we `JMP` to the known constant address, otherwise abort.
This protection is *near-precise*, i.e. it guarantees that the control flow will
be transferred to one of the valid return addresses for this function,
but not necessary to the point of the most recent `CALL`.
General case
------------
For functions called multiple times a *return jump table* is constructed
in the same manner as jump tables for indirect function calls (see above).
The correct jump table entry (or it's index) is passed by `CALL` to `f()`
(as an extra argument) and then spilled to stack.
The `RET` instruction is replaced with a load of the jump table entry,
jump table range check, and `JMP` to the jump table entry.
This protection is also *near-precise*.
Returns from functions called indirectly
----------------------------------------
If a function is called indirectly, the return jump table is constructed for the
equivalence class of functions instead of a single function.
Cross-DSO calls
---------------
Consider two instrumented DSOs, `A` and `B`. `A` defines `f()` and `B` calls it.
This case will be handled similarly to the cross-DSO scheme using the slow path callback.
Non-goals
---------
RCFI does not protect `RET` instructions:
* in non-instrumented DSOs,
* in instrumented DSOs for functions that are called from non-instrumented DSOs,
* embedded into other instructions (e.g. `0f4fc3 cmovg %ebx,%eax`).
.. _SafeStack: https://clang.llvm.org/docs/SafeStack.html
.. _RFG: http://xlab.tencent.com/en/2016/11/02/return-flow-guard
.. _Intel CET: https://software.intel.com/en-us/blogs/2016/06/09/intel-release-new-technology-specifications-protect-rop-attacks
Hardware support
================
We believe that the above design can be efficiently implemented in hardware.
A single new instruction added to an ISA would allow to perform the CFI check
A single new instruction added to an ISA would allow to perform the forward-edge CFI check
with fewer bytes per check (smaller code size overhead) and potentially more
efficiently. The current software-only instrumentation requires at least
32-bytes per check (on x86_64).
@ -540,7 +628,7 @@ The bit vector lookup is probably too complex for a hardware implementation.
Jump(kFailedCheckTarget);
}
An alternative and more compact enconding would not use `kFailedCheckTarget`,
An alternative and more compact encoding would not use `kFailedCheckTarget`,
and will trap on check failure instead.
This will allow us to fit the instruction into **8-9 bytes**.
The cross-DSO checks will be performed by a trap handler and

File diff suppressed because it is too large Load Diff

View File

@ -85,3 +85,16 @@ List of projects and tools
errors, fixit hints). See also `<http://l.rw.rw/clang_plugin>`_ for
step-by-step instructions."
`<https://phabricator.kde.org/source/clazy>`_
"clazy is a compiler plugin which allows clang to understand Qt semantics.
You get more than 50 Qt related compiler warnings, ranging from unneeded
memory allocations to misusage of API, including fix-its for automatic
refactoring."
`<https://gerrit.libreoffice.org/gitweb?p=core.git;a=blob_plain;f=compilerplugins/README;hb=HEAD>`_
"LibreOffice uses a Clang plugin infrastructure to check during the build
various things, some more, some less specific to the LibreOffice source code.
There are currently around 50 such checkers, from flagging C-style casts and
uses of reserved identifiers to ensuring that code adheres to lifecycle
protocols for certain LibreOffice-specific classes. They may serve as
examples for writing RecursiveASTVisitor-based plugins."

View File

@ -10,15 +10,16 @@ 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.
classes the whole-program devirtualization (``-fwhole-program-vtables``) and
control flow integrity (``-fsanitize=cfi-vcall``) 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
If any translation unit in the program uses either of the whole-program
devirtualization 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
units, but the tradeoff is that the whole-program devirtualization 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.

View File

@ -356,7 +356,7 @@ is:
Query for this feature with ``__has_extension(attribute_ext_vector_type)``.
Giving ``-faltivec`` option to clang enables support for AltiVec vector syntax
Giving ``-maltivec`` option to clang enables support for AltiVec vector syntax
and functions. For example:
.. code-block:: c++
@ -993,6 +993,7 @@ The following type trait primitives are supported by Clang:
* ``__has_trivial_destructor`` (GNU, Microsoft)
* ``__has_virtual_destructor`` (GNU, Microsoft)
* ``__is_abstract`` (GNU, Microsoft)
* ``__is_aggregate`` (GNU, Microsoft)
* ``__is_base_of`` (GNU, Microsoft)
* ``__is_class`` (GNU, Microsoft)
* ``__is_convertible_to`` (Microsoft)
@ -1780,7 +1781,7 @@ String builtins
---------------
Clang provides constant expression evaluation support for builtins forms of
the following functions from the C standard library ``<strings.h>`` header:
the following functions from the C standard library ``<string.h>`` header:
* ``memchr``
* ``memcmp``
@ -2312,3 +2313,36 @@ For example, the hint ``vectorize_width(4)`` is ignored if the loop is not
proven safe to vectorize. To identify and diagnose optimization issues use
`-Rpass`, `-Rpass-missed`, and `-Rpass-analysis` command line options. See the
user guide for details.
Extensions to specify floating-point flags
====================================================
The ``#pragma clang fp`` pragma allows floating-point options to be specified
for a section of the source code. This pragma can only appear at file scope or
at the start of a compound statement (excluding comments). When using within a
compound statement, the pragma is active within the scope of the compound
statement.
Currently, only FP contraction can be controlled with the pragma. ``#pragma
clang fp contract`` specifies whether the compiler should contract a multiply
and an addition (or subtraction) into a fused FMA operation when supported by
the target.
The pragma can take three values: ``on``, ``fast`` and ``off``. The ``on``
option is identical to using ``#pragma STDC FP_CONTRACT(ON)`` and it allows
fusion as specified the language standard. The ``fast`` option allows fusiong
in cases when the language standard does not make this possible (e.g. across
statements in C)
.. code-block:: c++
for(...) {
#pragma clang fp contract(fast)
a = b[i] * c[i];
d[i] += a;
}
The pragma can also be used with ``off`` which turns FP contraction off for a
section of the code. This can be useful when fast contraction is otherwise
enabled for the translation unit with the ``-ffp-contract=fast`` flag.

View File

@ -337,6 +337,15 @@ nonTypeTemplateParmDecl()
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('objcCategoryDecl0')"><a name="objcCategoryDecl0Anchor">objcCategoryDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCCategoryDecl.html">ObjCCategoryDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcCategoryDecl0"><pre>Matches Objective-C category declarations.
Example matches Foo (Additions)
@interface Foo (Additions)
@end
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('objcInterfaceDecl0')"><a name="objcInterfaceDecl0Anchor">objcInterfaceDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCInterfaceDecl.html">ObjCInterfaceDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcInterfaceDecl0"><pre>Matches Objective-C interface declarations.
@ -346,6 +355,50 @@ Example matches Foo
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('objcIvarDecl0')"><a name="objcIvarDecl0Anchor">objcIvarDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCIvarDecl.html">ObjCIvarDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcIvarDecl0"><pre>Matches Objective-C instance variable declarations.
Example matches _enabled
@implementation Foo {
BOOL _enabled;
}
@end
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('objcMethodDecl0')"><a name="objcMethodDecl0Anchor">objcMethodDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcMethodDecl0"><pre>Matches Objective-C method declarations.
Example matches both declaration and definition of -[Foo method]
@interface Foo
- (void)method;
@end
@implementation Foo
- (void)method {}
@end
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('objcPropertyDecl0')"><a name="objcPropertyDecl0Anchor">objcPropertyDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcPropertyDecl0"><pre>Matches Objective-C property declarations.
Example matches enabled
@interface Foo
@property BOOL enabled;
@end
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('objcProtocolDecl0')"><a name="objcProtocolDecl0Anchor">objcProtocolDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCProtocolDecl.html">ObjCProtocolDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcProtocolDecl0"><pre>Matches Objective-C protocol declarations.
Example matches FooDelegate
@protocol FooDelegate
@end
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('parmVarDecl0')"><a name="parmVarDecl0Anchor">parmVarDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="parmVarDecl0"><pre>Matches parameter variable declarations.
@ -416,6 +469,15 @@ typeAliasDecl()
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('typeAliasTemplateDecl0')"><a name="typeAliasTemplateDecl0Anchor">typeAliasTemplateDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeAliasTemplateDecl.html">TypeAliasTemplateDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="typeAliasTemplateDecl0"><pre>Matches type alias template declarations.
typeAliasTemplateDecl() matches
template &lt;typename T&gt;
using Y = X&lt;T&gt;;
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('typedefDecl0')"><a name="typedefDecl0Anchor">typedefDecl</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefDecl.html">TypedefDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="typedefDecl0"><pre>Matches typedef declarations.
@ -5419,7 +5481,7 @@ alignof.
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('forFunction0')"><a name="forFunction0Anchor">forFunction</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="forFunction0"><pre>Matches declaration of the function the statemenet belongs to
<tr><td colspan="4" class="doc" id="forFunction0"><pre>Matches declaration of the function the statement belongs to
Given:
F&amp; operator=(const F&amp; o) {

View File

@ -360,6 +360,7 @@ The ``framework`` qualifier specifies that this module corresponds to a Darwin-s
Name.framework/
Modules/module.modulemap Module map for the framework
Headers/ Subdirectory containing framework headers
PrivateHeaders/ Subdirectory containing framework private headers
Frameworks/ Subdirectory containing embedded frameworks
Resources/ Subdirectory containing additional resources
Name Symbolic link to the shared library for the framework
@ -842,6 +843,16 @@ would be available when ``Foo_Private.h`` is available, making it
easier to split a library's public and private APIs along header
boundaries.
When writing a private module as part of a *framework*, it's recommended that:
* Headers for this module are present in the ``PrivateHeaders``
framework subdirectory.
* The private module is defined as a *submodule* of the public framework (if
there's one), similar to how ``Foo.Private`` is defined in the example above.
* The ``explicit`` keyword should be used to guarantee that its content will
only be available when the submodule itself is explicitly named (through a
``@import`` for example).
Modularizing a Platform
=======================
To get any benefit out of modules, one needs to introduce module maps for software libraries starting at the bottom of the stack. This typically means introducing a module map covering the operating system's headers and the C standard library headers (in ``/usr/include``, for a Unix system).

View File

@ -1,6 +1,6 @@
=========================
Clang 4.0.0 Release Notes
=========================
=======================================
Clang 5.0.0 (In-Progress) Release Notes
=======================================
.. contents::
:local:
@ -8,11 +8,17 @@ Clang 4.0.0 Release Notes
Written by the `LLVM Team <http://llvm.org/>`_
.. warning::
These are in-progress notes for the upcoming Clang 5 release.
Release notes for previous releases can be found on
`the Download Page <http://releases.llvm.org/download.html>`_.
Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C/OpenCL
frontend, part of the LLVM Compiler Infrastructure, release 4.0.0. Here we
This document contains the release notes for the Clang C/C++/Objective-C
frontend, part of the LLVM Compiler Infrastructure, release 5.0.0. 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
@ -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 4.0.0?
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 5.0.0?
==========================
Some of the major new features and improvements to Clang are listed
@ -36,147 +47,165 @@ sections with improvements to Clang's support for those languages.
Major New Features
------------------
- The `diagnose_if <AttributeReference.html#diagnose-if>`_ attribute has been
added to clang. This attribute allows
clang to emit a warning or error if a function call meets one or more
user-specified conditions.
- ...
- Enhanced devirtualization with
`-fstrict-vtable-pointers <UsersManual.html#cmdoption-fstrict-vtable-pointers>`_.
Clang devirtualizes across different basic blocks, like loops:
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: c++
struct A {
virtual void foo();
};
void indirect(A &a, int n) {
for (int i = 0 ; i < n; i++)
a.foo();
}
void test(int n) {
A a;
indirect(a, n);
}
Improvements to ThinLTO (-flto=thin)
------------------------------------
- Integration with profile data (PGO). When available, profile data enables
more accurate function importing decisions, as well as cross-module indirect
call promotion.
- Significant build-time and binary-size improvements when compiling with debug
info (``-g``).
- -Wunused-lambda-capture warns when a variable explicitly captured
by a lambda is not used in the body of the lambda.
New Compiler Flags
------------------
- The option ``-Og`` has been added to optimize the debugging experience.
For now, this option is exactly the same as ``-O1``. However, in the future,
some other optimizations might be enabled or disabled.
The option ....
- The option ``-MJ`` has been added to simplify adding JSON compilation
database output into existing build systems.
New Pragmas in Clang
-----------------------
Clang now supports the ...
Attribute Changes in Clang
--------------------------
- ...
Windows Support
---------------
Clang's support for building native Windows programs ...
C Language Changes in Clang
---------------------------
- ...
...
C11 Feature Support
^^^^^^^^^^^^^^^^^^^
...
C++ Language Changes in Clang
-----------------------------
...
C++1z Feature Support
^^^^^^^^^^^^^^^^^^^^^
...
Objective-C Language Changes in Clang
-------------------------------------
...
OpenCL C Language Changes in Clang
----------------------------------
**The following bugs in the OpenCL header have been fixed:**
...
* Added missing ``overloadable`` and ``convergent`` attributes.
* Removed some erroneous extra ``native_*`` functions.
OpenMP Support in Clang
----------------------------------
**The following bugs in the generation of metadata have been fixed:**
...
* Corrected the SPIR version depending on the OpenCL version.
* Source level address spaces are taken from the SPIR specification.
* Image types now contain no access qualifier.
Internal API Changes
--------------------
**The following bugs in the AMD target have been fixed:**
These are major API changes that have happened since the 4.0.0 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.
* Corrected the bitwidth of ``size_t`` and NULL pointer value with respect to
address spaces.
* Added ``cl_khr_subgroups``, ``cl_amd_media_ops`` and ``cl_amd_media_ops2``
extensions.
* Added ``cl-denorms-are-zero`` support.
* Changed address spaces for image objects to be ``constant``.
* Added little-endian.
- ...
**The following bugs in OpenCL 2.0 have been fixed:**
AST Matchers
------------
* Fixed pipe builtin function return type, added extra argument to generated
IR intrinsics to propagate size and alignment information of the pipe packed
type.
* Improved pipe type to accommodate access qualifiers.
* Added correct address space to the ObjC block generation and ``enqueue_kernel``
prototype.
* Improved handling of integer parameters of ``enqueue_kernel`` prototype. We
now allow ``size_t`` instead of ``int`` for specifying block parameter sizes.
* Allow using NULL (aka ``CLK_NULL_QUEUE``) with ``queue_t``.
...
**Improved the following diagnostics:**
clang-format
------------
* Disallow address spaces other than ``global`` for kernel pointer parameters.
* Correct the use of half type argument and pointer assignment with
dereferencing.
* Disallow variadic arguments in functions and blocks.
* Allow partial initializer for array and struct.
* Option **BreakBeforeInheritanceComma** added to break before ``:`` and ``,`` in case of
multiple inheritance in a class declaration. Enabled by default in the Mozilla coding style.
**Some changes to OpenCL extensions have been made:**
+---------------------+----------------------------------------+
| true | false |
+=====================+========================================+
| .. code-block:: c++ | .. code-block:: c++ |
| | |
| class MyClass | class MyClass : public X, public Y { |
| : public X | }; |
| , public Y { | |
| }; | |
+---------------------+----------------------------------------+
* Added ``cl_khr_mipmap_image``.
* Added ``-cl-ext`` flag to allow overwriting supported extensions otherwise
set by the target compiled for (Example: ``-cl-ext=-all,+cl_khr_fp16``).
* New types and functions can now be flexibly added to extensions using the
following pragmas instead of modifying the Clang source code:
* Align block comment decorations.
.. code-block:: c
+----------------------+---------------------+
| Before | After |
+======================+=====================+
| .. code-block:: c++ | .. code-block:: c++ |
| | |
| /* line 1 | /* line 1 |
| * line 2 | * line 2 |
| */ | */ |
+----------------------+---------------------+
#pragma OPENCL EXTENSION the_new_extension_name : begin
// declare types and functions associated with the extension here
#pragma OPENCL EXTENSION the_new_extension_name : end
* The :doc:`ClangFormatStyleOptions` documentation provides detailed examples for most options.
* Namespace end comments are now added or updated automatically.
**Miscellaneous changes:**
+---------------------+---------------------+
| Before | After |
+=====================+=====================+
| .. code-block:: c++ | .. code-block:: c++ |
| | |
| namespace A { | namespace A { |
| int i; | int i; |
| int j; | int j; |
| } | } |
+---------------------+---------------------+
* Fix ``__builtin_astype`` to cast between different address space objects.
* Allow using ``opencl_unroll_hint`` with earlier OpenCL versions than 2.0.
* Improved handling of floating point literal to default to single precision if
fp64 extension is not enabled.
* Refactor ``sampler_t`` implementation to simplify initializer representation
which is now handled as a compiler builtin function with an integer value
passed into it.
* Change fake address space map to use the SPIR convention.
* Added `the OpenCL manual <UsersManual.html#opencl-features>`_ to Clang
documentation.
* Comment reflow support added. Overly long comment lines will now be reflown with the rest of
the paragraph instead of just broken. Option **ReflowComments** added and enabled by default.
libclang
--------
...
Static Analyzer
---------------
With the option ``--show-description``, scan-build's list of defects will also
show the description of the defects.
...
The analyzer now provides better support of code that uses gtest.
Core Analysis Improvements
==========================
Several new checks were added:
- ...
- The analyzer warns when virtual calls are made from constructors or
destructors. This check is off by default but can be enabled by passing the
following command to scan-build: ``-enable-checker optin.cplusplus.VirtualCall``.
- The analyzer checks for synthesized copy properties of mutable types in
Objective C, such as ``NSMutableArray``. Calling the setter for these properties
will store an immutable copy of the value.
- The analyzer checks for calls to ``dispatch_once()`` that use an Objective-C
instance variable as the predicate. Using an instance variable as a predicate
may result in the passed-in block being executed multiple times or not at all.
These calls should be rewritten either to use a lock or to store the predicate
in a global or static variable.
- The analyzer checks for unintended comparisons of ``NSNumber``, ``CFNumberRef``, and
other Cocoa number objects to scalar values.
New Issues Found
================
- ...
Python Binding Changes
----------------------
The following methods have been added:
- ...
Significant Known Problems
==========================
Additional Information
======================

View File

@ -227,7 +227,8 @@ easily used for bitset-based corpus distillation.
Caller-callee coverage
======================
(Experimental!)
**Deprecated, don't use**
Every indirect function call is instrumented with a run-time function call that
captures caller and callee. At the shutdown time the process dumps a separate
file called ``caller-callee.PID.sancov`` which contains caller/callee pairs as
@ -253,6 +254,8 @@ Current limitations:
Coverage counters
=================
**Deprecated, don't use**
This experimental feature is inspired by
`AFL <http://lcamtuf.coredump.cx/afl/technical_details.txt>`__'s coverage
instrumentation. With additional compile-time and run-time flags you can get
@ -296,6 +299,9 @@ These counters may also be used for in-process coverage-guided fuzzers. See
Tracing basic blocks
====================
**Deprecated, don't use**
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
@ -319,6 +325,9 @@ Basic block tracing is currently supported only for single-threaded applications
Tracing PCs
===========
**Deprecated, don't use**
*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.
@ -331,16 +340,13 @@ and can be used with `AFL <http://lcamtuf.coredump.cx/afl>`__.
Tracing PCs with guards
=======================
Another *experimental* feature that tries to combine the functionality of `trace-pc`,
`8bit-counters` and boolean coverage.
With ``-fsanitize-coverage=trace-pc-guard`` the compiler will insert the following code
on every edge:
.. code-block:: none
if (guard_variable)
__sanitizer_cov_trace_pc_guard(&guard_variable)
__sanitizer_cov_trace_pc_guard(&guard_variable)
Every edge will have its own `guard_variable` (uint32_t).
@ -349,10 +355,11 @@ The compler will also insert a module constructor that will call
.. code-block:: c++
// The guards are [start, stop).
// This function may be called multiple times with the same values of start/stop.
// This function will be called at least once per DSO and may be called
// more than once with the same values of start/stop.
__sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop);
Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,indirect-calls`
With `trace-pc-guards,indirect-calls`
``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.
The functions `__sanitizer_cov_trace_pc_*` should be defined by the user.
@ -367,10 +374,10 @@ Example:
#include <sanitizer/coverage_interface.h>
// This callback is inserted by the compiler as a module constructor
// into every compilation unit. 'start' and 'stop' correspond to the
// into every DSO. 'start' and 'stop' correspond to the
// beginning and end of the section with the guards for the entire
// binary (executable or DSO) and so it will be called multiple times
// with the same parameters.
// binary (executable or DSO). The callback will be called at least
// once per DSO and may be called multiple times with the same parameters.
extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
uint32_t *stop) {
static uint64_t N; // Counter for the guards.

View File

@ -18,6 +18,7 @@ Clang ships two other code coverage implementations:
various sanitizers. It can provide up to edge-level coverage.
* gcov - A GCC-compatible coverage implementation which operates on DebugInfo.
This is enabled by ``-ftest-coverage`` or ``--coverage``.
From this point onwards "code coverage" will refer to the source-based kind.
@ -256,6 +257,8 @@ without using static initializers, do this manually:
otherwise. Calling this function multiple times appends profile data to an
existing on-disk raw profile.
In C++ files, declare these as ``extern "C"``.
Collecting coverage reports for the llvm project
================================================

View File

@ -50,9 +50,9 @@ instead of ``clang++`` if you're compiling/linking C code.
You can enable only a subset of :ref:`checks <ubsan-checks>` offered by UBSan,
and define the desired behavior for each kind of check:
* print a verbose error report and continue execution (default);
* print a verbose error report and exit the program;
* execute a trap instruction (doesn't require UBSan run-time support).
* ``-fsanitize=...``: print a verbose error report and continue execution (default);
* ``-fno-sanitize-recover=...``: print a verbose error report and exit the program;
* ``-fsanitize-trap=...``: execute a trap instruction (doesn't require UBSan run-time support).
For example if you compile/link your program as:
@ -92,6 +92,12 @@ 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=nullability-arg``: Passing null as a function parameter
which is annotated with ``_Nonnull``.
- ``-fsanitize=nullability-assign``: Assigning null to an lvalue which
is annotated with ``_Nonnull``.
- ``-fsanitize=nullability-return``: Returning null from a function with
a return type annotated with ``_Nonnull``.
- ``-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
@ -117,7 +123,9 @@ Available checks are:
- ``-fsanitize=unreachable``: If control flow reaches
``__builtin_unreachable``.
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer
overflows.
overflows. Note that unlike signed integer overflow, unsigned integer
is not undefined behavior. However, while it has well-defined semantics,
it is often unintentional, so UBSan offers to catch it.
- ``-fsanitize=vla-bound``: A variable-length array whose bound
does not evaluate to a positive value.
- ``-fsanitize=vptr``: Use of an object whose vptr indicates that
@ -128,11 +136,15 @@ Available checks are:
You can also use the following check groups:
- ``-fsanitize=undefined``: All of the checks listed above other than
``unsigned-integer-overflow``.
``unsigned-integer-overflow`` and the ``nullability-*`` checks.
- ``-fsanitize=undefined-trap``: Deprecated alias of
``-fsanitize=undefined``.
- ``-fsanitize=integer``: Checks for undefined or suspicious integer
behavior (e.g. unsigned integer overflow).
- ``-fsanitize=nullability``: Enables ``nullability-arg``,
``nullability-assign``, and ``nullability-return``. While violating
nullability does not have undefined behavior, it is often unintentional,
so UBSan offers to catch it.
Stack traces and report symbolization
=====================================
@ -145,6 +157,8 @@ will need to:
``UBSAN_OPTIONS=print_stacktrace=1``.
#. Make sure ``llvm-symbolizer`` binary is in ``PATH``.
Stacktrace printing for UBSan issues is currently not supported on Darwin.
Issue Suppression
=================

View File

@ -562,6 +562,16 @@ control the crash diagnostics.
The -fno-crash-diagnostics flag can be helpful for speeding the process
of generating a delta reduced test case.
Clang is also capable of generating preprocessed source file(s) and associated
run script(s) even without a crash. This is specially useful when trying to
generate a reproducer for warnings or errors while using modules.
.. option:: -gen-reproducer
Generates preprocessed source files, a reproducer script and if relevant, a
cache containing: built module pcm's and all headers needed to rebuilt the
same modules.
.. _rpass:
Options to Emit Optimization Reports
@ -757,6 +767,7 @@ existed.
#if foo
#endif foo // warning: extra tokens at end of #endif directive
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wextra-tokens"
#if foo
@ -1695,6 +1706,22 @@ below. If multiple flags are present, the last one is used.
Generate complete debug info.
Controlling Macro Debug Info Generation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Debug info for C preprocessor macros increases the size of debug information in
the binary. Macro debug info generated by Clang can be controlled by the flags
listed below.
.. option:: -fdebug-macro
Generate debug info for preprocessor macros. This flag is discarded when
**-g0** is enabled.
.. option:: -fno-debug-macro
Do not generate debug info for preprocessor macros (default).
Controlling Debugger "Tuning"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -1862,7 +1889,7 @@ missing from this list, please send an e-mail to cfe-dev. This list
currently excludes C++; see :ref:`C++ Language Features <cxx>`. Also, this
list does not include bugs in mostly-implemented features; please see
the `bug
tracker <http://llvm.org/bugs/buglist.cgi?quicksearch=product%3Aclang+component%3A-New%2BBugs%2CAST%2CBasic%2CDriver%2CHeaders%2CLLVM%2BCodeGen%2Cparser%2Cpreprocessor%2CSemantic%2BAnalyzer>`_
tracker <https://bugs.llvm.org/buglist.cgi?quicksearch=product%3Aclang+component%3A-New%2BBugs%2CAST%2CBasic%2CDriver%2CHeaders%2CLLVM%2BCodeGen%2Cparser%2Cpreprocessor%2CSemantic%2BAnalyzer>`_
for known existing bugs (FIXME: Is there a section for bug-reporting
guidelines somewhere?).
@ -2273,7 +2300,7 @@ An example is the subgroup operations such as `intel_sub_group_shuffle
// Define custom my_sub_group_shuffle(data, c)
// that makes use of intel_sub_group_shuffle
r1 =
r1 = ...
if (r0) r1 = computeA();
// Shuffle data from r1 into r3
// of threads id r2.
@ -2284,7 +2311,7 @@ with non-SPMD semantics this is optimized to the following equivalent code:
.. code-block:: c
r1 =
r1 = ...
if (!r0)
// Incorrect functionality! The data in r1
// have not been computed by all threads yet.
@ -2499,7 +2526,7 @@ official `MinGW-w64 website <http://mingw-w64.sourceforge.net>`_.
Clang expects the GCC executable "gcc.exe" compiled for
``i686-w64-mingw32`` (or ``x86_64-w64-mingw32``) to be present on PATH.
`Some tests might fail <http://llvm.org/bugs/show_bug.cgi?id=9072>`_ on
`Some tests might fail <https://bugs.llvm.org/show_bug.cgi?id=9072>`_ on
``x86_64-w64-mingw32``.
.. _clang-cl:
@ -2542,7 +2569,7 @@ options are spelled with a leading ``/``, they will be mistaken for a filename:
clang-cl.exe: error: no such file or directory: '/foobar'
Please `file a bug <http://llvm.org/bugs/enter_bug.cgi?product=clang&component=Driver>`_
Please `file a bug <https://bugs.llvm.org/enter_bug.cgi?product=clang&component=Driver>`_
for any valid cl.exe flags that clang-cl does not understand.
Execute ``clang-cl /?`` to see a list of supported options:

View File

@ -178,15 +178,21 @@ ExprInspection checks
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.
or even record-type values. To simplify usage in C code (where overloading
the function declaration is not allowed), you may append an arbitrary suffix
to the function name, without affecting functionality.
Example usage::
void clang_analyzer_explain(int);
void clang_analyzer_explain(void *);
// Useful in C code
void clang_analyzer_explain_int(int);
void foo(int param, void *ptr) {
clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}}
if (!ptr)
clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
}

View File

@ -48,10 +48,10 @@
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '4.0'
# The short version.
version = '5'
# The full version, including alpha/beta/rc tags.
release = '4.0'
release = '5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -48,10 +48,10 @@
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '4'
# The short version.
version = '5'
# The full version, including alpha/beta/rc tags.
release = '4'
release = '5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -1885,7 +1885,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO
MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
@ -1893,7 +1893,7 @@ MACRO_EXPANSION = NO
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO
EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES the includes files in the
# INCLUDE_PATH will be searched if a #include is found.
@ -1925,7 +1925,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
PREDEFINED = LLVM_ALIGNAS(x)=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The

View File

@ -19,6 +19,7 @@ Using Clang as a Compiler
UsersManual
Toolchain
LanguageExtensions
ClangCommandLineReference
AttributeReference
DiagnosticsReference
CrossCompilation

View File

@ -19,7 +19,6 @@ def substitute(text, tag, contents):
return re.sub(pattern, '%s', text, flags=re.S) % replacement
def doxygen2rst(text):
text = re.sub(r'([^/\*])\*', r'\1\\*', text)
text = re.sub(r'<tt>\s*(.*?)\s*<\/tt>', r'``\1``', text)
text = re.sub(r'\\c ([^ ,;\.]+)', r'``\1``', text)
text = re.sub(r'\\\w+ ', '', text)
@ -65,7 +64,7 @@ def __init__(self, name, comment):
self.comment = comment.strip()
def __str__(self):
return '* ``%s`` %s' % (self.name, doxygen2rst(self.comment))
return '\n* ``%s`` %s' % (self.name, doxygen2rst(self.comment))
class Enum:
def __init__(self, name, comment):

View File

@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
MC
MCJIT
Option
Support
native
)

View File

@ -478,8 +478,8 @@ CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location,
unsigned *offset);
/**
* \brief Retrieve the file, line, column, and offset represented by
* the given source location, as specified in a # line directive.
* \brief Retrieve the file, line and column represented by the given source
* location, as specified in a # line directive.
*
* Example: given the following source code in a file somefile.c
*
@ -3011,8 +3011,9 @@ enum CXTypeKind {
CXType_ObjCClass = 28,
CXType_ObjCSel = 29,
CXType_Float128 = 30,
CXType_Half = 31,
CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_ObjCSel,
CXType_LastBuiltin = CXType_Half,
CXType_Complex = 100,
CXType_Pointer = 101,
@ -3435,6 +3436,16 @@ CINDEX_LINKAGE long long clang_getArraySize(CXType T);
*/
CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
/**
* \brief Determine if a typedef is 'transparent' tag.
*
* A typedef is considered 'transparent' if it shares a name and spelling
* location with its underlying tag type, as is the case with the NS_ENUM macro.
*
* \returns non-zero if transparent and zero otherwise.
*/
CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
/**
* \brief List the possible error codes for \c clang_Type_getSizeOf,
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
@ -4023,8 +4034,8 @@ CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
/**
* \brief Given a cursor that represents an Objective-C method or property
* declaration, return non-zero if the declaration was affected by "@optional".
* Returns zero if the cursor is not such a declaration or it is "@required".
* declaration, return non-zero if the declaration was affected by "\@optional".
* Returns zero if the cursor is not such a declaration or it is "\@required".
*/
CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
@ -4700,7 +4711,7 @@ enum CXCompletionChunkKind {
*/
CXCompletionChunk_HorizontalSpace,
/**
* Vertical space ('\n'), after which it is generally a good idea to
* Vertical space ('\\n'), after which it is generally a good idea to
* perform indentation.
*/
CXCompletionChunk_VerticalSpace

View File

@ -39,6 +39,7 @@
#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/XRayLists.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@ -66,6 +67,7 @@
#include <memory>
#include <new>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
@ -167,18 +169,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentUnaryTransformType>
DependentUnaryTransformTypes;
mutable llvm::FoldingSet<AutoType> AutoTypes;
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
llvm::FoldingSet<AttributedType> AttributedTypes;
mutable llvm::FoldingSet<PipeType> PipeTypes;
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
SubstTemplateTemplateParms;
mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
ASTContext&>
ASTContext&>
SubstTemplateTemplateParmPacks;
/// \brief The set of nested name specifiers.
///
/// This set is managed by the NestedNameSpecifier class.
@ -200,17 +204,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief A cache mapping from CXXRecordDecls to key functions.
llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
/// \brief Mapping from ObjCContainers to their ObjCImplementations.
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
/// \brief Mapping from ObjCMethod to its duplicate declaration in the same
/// interface.
llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
/// \brief Mapping from __block VarDecls to their copy initialization expr.
llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
/// \brief Mapping from class scope functions specialization to their
/// template patterns.
llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
@ -226,21 +230,21 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// is used in canonical template names.
class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
TemplateTemplateParmDecl *Parm;
public:
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
: Parm(Parm) { }
TemplateTemplateParmDecl *getParam() const { return Parm; }
void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
static void Profile(llvm::FoldingSetNodeID &ID,
static void Profile(llvm::FoldingSetNodeID &ID,
TemplateTemplateParmDecl *Parm);
};
mutable llvm::FoldingSet<CanonicalTemplateTemplateParm>
CanonTemplateTemplateParms;
TemplateTemplateParmDecl *
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
@ -259,7 +263,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief The typedef for the predefined \c id type.
mutable TypedefDecl *ObjCIdDecl;
/// \brief The typedef for the predefined \c SEL type.
mutable TypedefDecl *ObjCSelDecl;
@ -268,7 +272,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief The typedef for the predefined \c Protocol class in Objective-C.
mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
/// \brief The typedef for the predefined 'BOOL' type.
mutable TypedefDecl *BOOLDecl;
@ -298,12 +302,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable TypedefDecl *CFConstantStringTypeDecl;
mutable QualType ObjCSuperType;
QualType ObjCNSStringType;
/// \brief The typedef declaration for the Objective-C "instancetype" type.
TypedefDecl *ObjCInstanceTypeDecl;
/// \brief The type for the C FILE type.
TypeDecl *FILEDecl;
@ -451,11 +455,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
ParameterIndexTable ParamIndices;
ParameterIndexTable ParamIndices;
ImportDecl *FirstLocalImport;
ImportDecl *LastLocalImport;
TranslationUnitDecl *TUDecl;
mutable ExternCContextDecl *ExternCContext;
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
@ -472,6 +476,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// entities should not be instrumented.
std::unique_ptr<SanitizerBlacklist> SanitizerBL;
/// \brief Function filtering mechanism to determine whether a given function
/// should be imbued with the XRay "always" or "never" attributes.
std::unique_ptr<XRayFunctionFilter> XRayFilter;
/// \brief The allocator used to create AST objects.
///
/// AST objects are never destructed; rather, all memory associated with the
@ -488,7 +496,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief The logical -> physical address space map.
const LangAS::Map *AddrSpaceMap;
/// \brief Address space map mangling must be used with language specific
/// \brief Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA)
bool AddrSpaceMapMangling;
@ -500,7 +508,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
const TargetInfo *Target;
const TargetInfo *AuxTarget;
clang::PrintingPolicy PrintingPolicy;
public:
IdentifierTable &Idents;
SelectorTable &Selectors;
@ -604,7 +612,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
PrintingPolicy = Policy;
}
SourceManager& getSourceManager() { return SourceMgr; }
const SourceManager& getSourceManager() const { return SourceMgr; }
@ -619,7 +627,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
}
void Deallocate(void *Ptr) const { }
/// Return the total amount of physical memory allocated for representing
/// AST nodes and type information.
size_t getASTAllocatedMemory() const {
@ -627,7 +635,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
/// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const;
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
return DiagAllocator;
}
@ -647,13 +655,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getRealTypeForBitwidth(unsigned DestWidth) const;
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
const LangOptions& getLangOpts() const { return LangOpts; }
const SanitizerBlacklist &getSanitizerBlacklist() const {
return *SanitizerBL;
}
const XRayFunctionFilter &getXRayFilter() const {
return *XRayFilter;
}
DiagnosticsEngine &getDiagnostics() const;
FullSourceLoc getFullLoc(SourceLocation Loc) const {
@ -862,7 +874,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
// Access to the set of methods overridden by the given C++ method.
typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
overridden_cxx_method_iterator
@ -878,7 +890,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Note that the given C++ \p Method overrides the given \p
/// Overridden method.
void addOverriddenMethod(const CXXMethodDecl *Method,
void addOverriddenMethod(const CXXMethodDecl *Method,
const CXXMethodDecl *Overridden);
/// \brief Return C++ or ObjC overridden methods for the given \p Method.
@ -891,7 +903,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
void getOverriddenMethods(
const NamedDecl *Method,
SmallVectorImpl<const NamedDecl *> &Overridden) const;
/// \brief Notify the AST context that a new import declaration has been
/// parsed or implicitly created within this translation unit.
void addedLocalImportDecl(ImportDecl *Import);
@ -899,7 +911,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
static ImportDecl *getNextLocalImport(ImportDecl *Import) {
return Import->NextLocalImport;
}
typedef llvm::iterator_range<import_iterator> import_range;
import_range local_imports() const {
return import_range(import_iterator(FirstLocalImport), import_iterator());
@ -973,7 +985,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
CanQualType SingletonId;
#include "clang/Basic/OpenCLImageTypes.def"
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
CanQualType OCLQueueTy, OCLReserveIDTy;
CanQualType OMPArraySectionTy;
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
@ -1179,15 +1191,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
/// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
/// to false in this case. If HasByrefExtendedLayout returns true, byref variable
/// has extended lifetime.
/// has extended lifetime.
bool getByrefLifetime(QualType Ty,
Qualifiers::ObjCLifetime &Lifetime,
bool &HasByrefExtendedLayout) const;
/// \brief Return the uniqued reference to the type for an lvalue reference
/// to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
@ -1231,7 +1243,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
/// \brief Returns a vla type where known sizes are replaced with [*].
QualType getVariableArrayDecayedType(QualType Ty) const;
@ -1355,6 +1367,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl);
/// Get a template argument list with one argument per template parameter
/// in a template parameter list, such as for the injected class name of
/// a class template.
@ -1380,7 +1394,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
ArrayRef<ObjCProtocolDecl *> protocols,
QualType Canonical = QualType()) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
/// QT's qualified-id protocol list adopt all protocols in IDecl's list
@ -1412,6 +1426,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
/// \brief C++1z deduced class template specialization type.
QualType getDeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedType,
bool IsDependent) const;
/// \brief Return the unique reference to the type for the specified TagDecl
/// (struct/union/class/enum) decl.
QualType getTagDeclType(const TagDecl *Decl) const;
@ -1471,11 +1490,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Return the C structure type used to represent constant CFStrings.
QualType getCFConstantStringType() const;
/// \brief Returns the C struct type for objc_super
QualType getObjCSuperType() const;
void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
/// Get the structure type used to representation CFStrings, or NULL
/// if it hasn't yet been built.
QualType getRawCFConstantStringType() const {
@ -1496,11 +1515,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getObjCNSStringType() const {
return ObjCNSStringType;
}
void setObjCNSStringType(QualType T) {
ObjCNSStringType = T;
}
/// \brief Retrieve the type that \c id has been defined to, which may be
/// different from the built-in \c id if \c id has been typedef'd.
QualType getObjCIdRedefinitionType() const {
@ -1508,7 +1527,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getObjCIdType();
return ObjCIdRedefinitionType;
}
/// \brief Set the user-written type that redefines \c id.
void setObjCIdRedefinitionType(QualType RedefType) {
ObjCIdRedefinitionType = RedefType;
@ -1521,7 +1540,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getObjCClassType();
return ObjCClassRedefinitionType;
}
/// \brief Set the user-written type that redefines 'SEL'.
void setObjCClassRedefinitionType(QualType RedefType) {
ObjCClassRedefinitionType = RedefType;
@ -1534,7 +1553,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getObjCSelType();
return ObjCSelRedefinitionType;
}
/// \brief Set the user-written type that redefines 'SEL'.
void setObjCSelRedefinitionType(QualType RedefType) {
ObjCSelRedefinitionType = RedefType;
@ -1586,7 +1605,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Retrieve the typedef declaration corresponding to the Objective-C
/// "instancetype" type.
TypedefDecl *getObjCInstanceTypeDecl();
/// \brief Set the type for the C FILE type.
void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
@ -1671,7 +1690,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Return the encoded type for this block declaration.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
/// getObjCEncodingForPropertyDecl - Return the encoded type for
/// this method declaration. If non-NULL, Container must be either
/// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
@ -1681,7 +1700,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
const ObjCPropertyDecl *PD,
const Decl *Container) const;
@ -1693,7 +1712,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Retrieve the typedef corresponding to the predefined \c id type
/// in Objective-C.
TypedefDecl *getObjCIdDecl() const;
/// \brief Represents the Objective-CC \c id type.
///
/// This is set up lazily, by Sema. \c id is always a (typedef for a)
@ -1705,26 +1724,26 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Retrieve the typedef corresponding to the predefined 'SEL' type
/// in Objective-C.
TypedefDecl *getObjCSelDecl() const;
/// \brief Retrieve the type that corresponds to the predefined Objective-C
/// 'SEL' type.
QualType getObjCSelType() const {
QualType getObjCSelType() const {
return getTypeDeclType(getObjCSelDecl());
}
/// \brief Retrieve the typedef declaration corresponding to the predefined
/// Objective-C 'Class' type.
TypedefDecl *getObjCClassDecl() const;
/// \brief Represents the Objective-C \c Class type.
///
/// This is set up lazily, by Sema. \c Class is always a (typedef for a)
/// pointer type, a pointer to a struct.
QualType getObjCClassType() const {
QualType getObjCClassType() const {
return getTypeDeclType(getObjCClassDecl());
}
/// \brief Retrieve the Objective-C class declaration corresponding to
/// \brief Retrieve the Objective-C class declaration corresponding to
/// the predefined \c Protocol class.
ObjCInterfaceDecl *getObjCProtocolDecl() const;
@ -1742,12 +1761,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getBOOLType() const {
return getTypeDeclType(getBOOLDecl());
}
/// \brief Retrieve the type of the Objective-C \c Protocol class.
QualType getObjCProtoType() const {
return getObjCInterfaceType(getObjCProtocolDecl());
}
/// \brief Retrieve the C type declaration corresponding to the predefined
/// \c __builtin_va_list type.
TypedefDecl *getBuiltinVaListDecl() const;
@ -1810,7 +1829,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
qs.addObjCLifetime(lifetime);
return getQualifiedType(type, qs);
}
/// getUnqualifiedObjCPointerType - Returns version of
/// Objective-C pointer type with lifetime qualifier removed.
QualType getUnqualifiedObjCPointerType(QualType type) const {
@ -1821,7 +1840,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
Qs.removeObjCLifetime();
return getQualifiedType(type.getUnqualifiedType(), Qs);
}
DeclarationNameInfo getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const;
@ -1840,7 +1859,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateName replacement) const;
TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
const TemplateArgument &ArgPack) const;
enum GetBuiltinTypeError {
GE_None, ///< No error
GE_Missing_stdio, ///< Missing a type from <stdio.h>
@ -1905,7 +1924,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
uint64_t getCharWidth() const {
return getTypeSize(CharTy);
}
/// \brief Convert a size in bits to a size in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const;
@ -1927,11 +1946,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// example, from alignment attributes).
unsigned getTypeAlignIfKnown(QualType T) const;
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
CharUnits getTypeAlignInChars(QualType T) const;
CharUnits getTypeAlignInChars(const Type *T) const;
// getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
// type is a record, its data size is returned.
std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
@ -2036,10 +2055,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
VTableContextBase *getVTableContext();
MangleContext *createMangleContext();
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
@ -2115,7 +2134,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
*SubTnullability == NullabilityKind::Unspecified ||
*SuperTnullability == NullabilityKind::Unspecified)
return true;
if (IsParam) {
// Ok for the superclass method parameter to be "nonnull" and the subclass
// method parameter to be "nullable"
@ -2134,9 +2153,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
const ObjCMethodDecl *MethodImp);
bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
/// \brief Retrieves the "canonical" nested name specifier for a
/// given nested name specifier.
///
@ -2190,7 +2209,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Determine whether the given template names refer to the same
/// template.
bool hasSameTemplateName(TemplateName X, TemplateName Y);
/// \brief Retrieve the "canonical" template argument.
///
/// The canonical template argument is the simplest template argument
@ -2217,7 +2236,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
const {
return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
}
/// \brief Return the innermost element type of an array type.
///
/// For example, will return "int" for int[m][n]
@ -2236,14 +2255,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
/// C++ [dcl.fct]p3). The adjusted parameter type is returned.
QualType getAdjustedParameterType(QualType T) const;
/// \brief Retrieve the parameter type as adjusted for use in the signature
/// of a function, decaying array and function types and removing top-level
/// cv-qualifiers.
QualType getSignatureParameterType(QualType T) const;
QualType getExceptionObjectType(QualType T) const;
/// \brief Return the properly qualified result of decaying the specified
/// array type to a pointer.
///
@ -2269,7 +2288,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// promotion occurs.
QualType isPromotableBitField(Expr *E) const;
/// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
/// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
///
/// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
/// \p LHS < \p RHS, return -1.
@ -2298,12 +2317,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getTargetAddressSpace(Q.getAddressSpace());
}
unsigned getTargetAddressSpace(unsigned AS) const {
if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
return AS;
else
return (*AddrSpaceMap)[AS - LangAS::Offset];
}
unsigned getTargetAddressSpace(unsigned AS) const;
/// Get target-dependent integer value for null pointer which is used for
/// constant folding.
@ -2311,8 +2325,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool addressSpaceMapManglingFor(unsigned AS) const {
return AddrSpaceMapMangling ||
AS < LangAS::Offset ||
AS >= LangAS::Offset + LangAS::Count;
AS >= LangAS::Count;
}
private:
@ -2325,11 +2338,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
//===--------------------------------------------------------------------===//
/// Compatibility predicates used to check assignment expressions.
bool typesAreCompatible(QualType T1, QualType T2,
bool typesAreCompatible(QualType T1, QualType T2,
bool CompareUnqualified = false); // C99 6.2.7p1
bool propertyTypesAreCompatible(QualType, QualType);
bool typesAreBlockPointerCompatible(QualType, QualType);
bool propertyTypesAreCompatible(QualType, QualType);
bool typesAreBlockPointerCompatible(QualType, QualType);
bool isObjCIdType(QualType T) const {
return T == getObjCIdType();
@ -2344,7 +2357,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool ForCompare);
bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
// Check the safety of assignment from LHS to RHS
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@ -2370,9 +2383,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType mergeTransparentUnionType(QualType, QualType,
bool OfBlockPointer=false,
bool Unqualified = false);
QualType mergeObjCGCQualifiers(QualType, QualType);
bool doFunctionTypesMatchOnExtParameterInfos(
const FunctionProtoType *FromFunctionType,
const FunctionProtoType *ToFunctionType);
@ -2442,7 +2455,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// an Objective-C method/property/ivar etc. that is part of an interface,
/// otherwise returns null.
const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
/// \brief Set the copy inialization expression of a block var decl.
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
/// \brief Get the copy initialization expression of the VarDecl \p VD, or
@ -2466,10 +2479,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// initialized to a given location, which defaults to the empty
/// location.
TypeSourceInfo *
getTrivialTypeSourceInfo(QualType T,
getTrivialTypeSourceInfo(QualType T,
SourceLocation Loc = SourceLocation()) const;
/// \brief Add a deallocation callback that will be invoked when the
/// \brief Add a deallocation callback that will be invoked when the
/// ASTContext is destroyed.
///
/// \param Callback A callback function that will be invoked on destruction.
@ -2478,6 +2491,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
/// If T isn't trivially destructible, calls AddDeallocation to register it
/// for destruction.
template <typename T>
void addDestruction(T *Ptr) {
if (!std::is_trivially_destructible<T>::value) {
auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
AddDeallocation(DestroyPtr, Ptr);
}
}
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
@ -2534,15 +2557,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief The number of implicitly-declared default constructors.
static unsigned NumImplicitDefaultConstructors;
/// \brief The number of implicitly-declared default constructors for
/// \brief The number of implicitly-declared default constructors for
/// which declarations were built.
static unsigned NumImplicitDefaultConstructorsDeclared;
/// \brief The number of implicitly-declared copy constructors.
static unsigned NumImplicitCopyConstructors;
/// \brief The number of implicitly-declared copy constructors for
/// \brief The number of implicitly-declared copy constructors for
/// which declarations were built.
static unsigned NumImplicitCopyConstructorsDeclared;
@ -2555,25 +2578,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief The number of implicitly-declared copy assignment operators.
static unsigned NumImplicitCopyAssignmentOperators;
/// \brief The number of implicitly-declared copy assignment operators for
/// \brief The number of implicitly-declared copy assignment operators for
/// which declarations were built.
static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
/// \brief The number of implicitly-declared move assignment operators.
static unsigned NumImplicitMoveAssignmentOperators;
/// \brief The number of implicitly-declared move assignment operators for
/// \brief The number of implicitly-declared move assignment operators for
/// which declarations were built.
static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
/// \brief The number of implicitly-declared destructors.
static unsigned NumImplicitDestructors;
/// \brief The number of implicitly-declared destructors for which
/// \brief The number of implicitly-declared destructors for which
/// declarations were built.
static unsigned NumImplicitDestructorsDeclared;
public:
/// \brief Initialize built-in types.
///

View File

@ -22,6 +22,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <memory>

View File

@ -169,9 +169,6 @@ BUILTIN_TYPE(OCLClkEvent, OCLClkEventTy)
// OpenCL queue_t.
BUILTIN_TYPE(OCLQueue, OCLQueueTy)
// OpenCL ndrange_t.
BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy)
// OpenCL reserve_id_t.
BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)

View File

@ -838,7 +838,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// Describes the kind of default argument for this parameter. By default
/// this is none. If this is normal, then the default argument is stored in
/// the \c VarDecl initalizer expression unless we were unble to parse
/// the \c VarDecl initializer expression unless we were unable to parse
/// (even an invalid) expression for the default argument.
unsigned DefaultArgKind : 2;
@ -1605,9 +1605,14 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
// FIXME: This can be packed into the bitfields in DeclContext.
// NOTE: VC++ packs bitfields poorly if the types differ.
unsigned SClass : 2;
unsigned SClass : 3;
unsigned IsInline : 1;
unsigned IsInlineSpecified : 1;
protected:
// This is shared by CXXConstructorDecl, CXXConversionDecl, and
// CXXDeductionGuideDecl.
unsigned IsExplicitSpecified : 1;
private:
unsigned IsVirtualAsWritten : 1;
unsigned IsPure : 1;
unsigned HasInheritedPrototype : 1;
@ -1708,8 +1713,9 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
StartLoc),
DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
SClass(S), IsInline(isInlineSpecified),
IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
IsInlineSpecified(isInlineSpecified), IsExplicitSpecified(false),
IsVirtualAsWritten(false), IsPure(false),
HasInheritedPrototype(false), HasWrittenPrototype(true),
IsDeleted(false), IsTrivial(false), IsDefaulted(false),
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
@ -2635,12 +2641,17 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
// FIXME: This can be packed into the bitfields in Decl.
/// If 0, we have not computed IsTransparentTag.
/// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
mutable unsigned CacheIsTransparentTag : 2;
protected:
TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
MaybeModedTInfo(TInfo) {}
MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
TypedefNameDecl *getNextRedeclarationImpl() override {
@ -2693,11 +2704,22 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
/// this typedef declaration.
TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
/// Determines if this typedef shares a name and spelling location with its
/// underlying tag type, as is the case with the NS_ENUM macro.
bool isTransparentTag() const {
if (CacheIsTransparentTag)
return CacheIsTransparentTag & 0x2;
return isTransparentTagSlow();
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K >= firstTypedefName && K <= lastTypedefName;
}
private:
bool isTransparentTagSlow() const;
};
/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
@ -3229,6 +3251,18 @@ class EnumDecl : public TagDecl {
return isCompleteDefinition() || isFixed();
}
/// Returns true if this enum is either annotated with
/// enum_extensibility(closed) or isn't annotated with enum_extensibility.
bool isClosed() const;
/// Returns true if this enum is annotated with flag_enum and isn't annotated
/// with enum_extensibility(open).
bool isClosedFlag() const;
/// Returns true if this enum is annotated with neither flag_enum nor
/// enum_extensibility(open).
bool isClosedNonFlag() const;
/// \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;

View File

@ -654,20 +654,19 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
/// a precompiled header or module) rather than having been parsed.
bool isFromASTFile() const { return FromASTFile; }
/// \brief Retrieve the global declaration ID associated with this
/// declaration, which specifies where in the
unsigned getGlobalID() const {
/// \brief Retrieve the global declaration ID associated with this
/// declaration, which specifies where this Decl was loaded from.
unsigned getGlobalID() const {
if (isFromASTFile())
return *((const unsigned*)this - 1);
return 0;
}
/// \brief Retrieve the global ID of the module that owns this particular
/// declaration.
unsigned getOwningModuleID() const {
if (isFromASTFile())
return *((const unsigned*)this - 2);
return 0;
}
@ -1030,7 +1029,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
void dump() const;
// Same as dump(), but forces color printing.
void dumpColor() const;
void dump(raw_ostream &Out) const;
void dump(raw_ostream &Out, bool Deserialize = false) const;
/// \brief Looks through the Decl's underlying type to extract a FunctionType
/// when possible. Will return null if the type underlying the Decl does not
@ -1811,7 +1810,8 @@ class DeclContext {
void dumpDeclContext() const;
void dumpLookups() const;
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
bool Deserialize = false) const;
private:
void reconcileExternalVisibleStorage() const;

View File

@ -203,6 +203,11 @@ class CXXBaseSpecifier {
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
/// \brief Get the location at which the base class type was written.
SourceLocation getBaseTypeLoc() const LLVM_READONLY {
return BaseTypeInfo->getTypeLoc().getLocStart();
}
/// \brief Determines whether the base class is a virtual base class (or not).
bool isVirtual() const { return Virtual; }
@ -436,9 +441,10 @@ class CXXRecordDecl : public RecordDecl {
/// either by the user or implicitly.
unsigned DeclaredSpecialMembers : 6;
/// \brief Whether an implicit copy constructor would have a const-qualified
/// parameter.
unsigned ImplicitCopyConstructorHasConstParam : 1;
/// \brief Whether an implicit copy constructor could have a const-qualified
/// parameter, for initializing virtual bases and for other subobjects.
unsigned ImplicitCopyConstructorCanHaveConstParamForVBase : 1;
unsigned ImplicitCopyConstructorCanHaveConstParamForNonVBase : 1;
/// \brief Whether an implicit copy assignment operator would have a
/// const-qualified parameter.
@ -458,6 +464,11 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Whether we are currently parsing base specifiers.
unsigned IsParsingBaseSpecifiers : 1;
unsigned HasODRHash : 1;
/// \brief A hash of parts of the class to help in ODR checking.
unsigned ODRHash;
/// \brief The number of base class specifiers in Bases.
unsigned NumBases;
@ -703,6 +714,8 @@ class CXXRecordDecl : public RecordDecl {
return data().IsParsingBaseSpecifiers;
}
unsigned getODRHash() const;
/// \brief Sets the base classes of this struct or class.
void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
@ -871,7 +884,9 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Determine whether an implicit copy constructor for this type
/// would have a parameter with a const-qualified reference type.
bool implicitCopyConstructorHasConstParam() const {
return data().ImplicitCopyConstructorHasConstParam;
return data().ImplicitCopyConstructorCanHaveConstParamForNonVBase &&
(isAbstract() ||
data().ImplicitCopyConstructorCanHaveConstParamForVBase);
}
/// \brief Determine whether this class has a copy constructor with
@ -1738,6 +1753,58 @@ class CXXRecordDecl : public RecordDecl {
friend class ASTWriter;
};
/// \brief Represents a C++ deduction guide declaration.
///
/// \code
/// template<typename T> struct A { A(); A(T); };
/// A() -> A<int>;
/// \endcode
///
/// In this example, there will be an explicit deduction guide from the
/// second line, and implicit deduction guide templates synthesized from
/// the constructors of \c A.
class CXXDeductionGuideDecl : public FunctionDecl {
void anchor() override;
private:
CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
bool IsExplicit, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
SourceLocation EndLocation)
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
SC_None, false, false) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
IsExplicitSpecified = IsExplicit;
}
public:
static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, bool IsExplicit,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
SourceLocation EndLocation);
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Whether this deduction guide is explicit.
bool isExplicit() const { return IsExplicitSpecified; }
/// Whether this deduction guide was declared with the 'explicit' specifier.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
/// Get the template for which this guide performs deduction.
TemplateDecl *getDeducedTemplate() const {
return getDeclName().getCXXDeductionGuideTemplate();
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
/// \brief Represents a static or instance method of a struct/union/class.
///
/// In the terminology of the C++ Standard, these are the (static and
@ -2161,13 +2228,9 @@ class CXXConstructorDecl final
/// \{
/// \brief The arguments used to initialize the base or member.
LazyCXXCtorInitializersPtr CtorInitializers;
unsigned NumCtorInitializers : 30;
unsigned NumCtorInitializers : 31;
/// \}
/// \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;
@ -2181,11 +2244,11 @@ class CXXConstructorDecl final
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
CtorInitializers(nullptr), NumCtorInitializers(0),
IsExplicitSpecified(isExplicitSpecified),
IsInheritingConstructor((bool)Inherited) {
setImplicit(isImplicitlyDeclared);
if (Inherited)
*getTrailingObjects<InheritedConstructor>() = Inherited;
IsExplicitSpecified = isExplicitSpecified;
}
public:
@ -2198,15 +2261,6 @@ class CXXConstructorDecl final
bool isConstexpr,
InheritedConstructor Inherited = InheritedConstructor());
/// \brief Determine whether this constructor declaration has the
/// \c explicit keyword specified.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
/// \brief Determine whether this constructor was marked "explicit" or not.
bool isExplicit() const {
return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
}
/// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer **init_iterator;
@ -2270,6 +2324,14 @@ class CXXConstructorDecl final
CtorInitializers = Initializers;
}
/// Whether this function is marked as explicit explicitly.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
/// Whether this function is explicit.
bool isExplicit() const {
return getCanonicalDecl()->isExplicitSpecified();
}
/// \brief Determine whether this constructor is a delegating constructor.
bool isDelegatingConstructor() const {
return (getNumCtorInitializers() == 1) &&
@ -2405,7 +2467,14 @@ class CXXDestructorDecl : public CXXMethodDecl {
void setOperatorDelete(FunctionDecl *OD);
const FunctionDecl *getOperatorDelete() const {
return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
return getCanonicalDecl()->OperatorDelete;
}
CXXDestructorDecl *getCanonicalDecl() override {
return cast<CXXDestructorDecl>(FunctionDecl::getCanonicalDecl());
}
const CXXDestructorDecl *getCanonicalDecl() const {
return const_cast<CXXDestructorDecl*>(this)->getCanonicalDecl();
}
// Implement isa/cast/dyncast/etc.
@ -2428,19 +2497,16 @@ class CXXDestructorDecl : public CXXMethodDecl {
/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
void anchor() override;
/// Whether this conversion function declaration is marked
/// "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++11 feature.
bool IsExplicitSpecified : 1;
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified,
bool isConstexpr, SourceLocation EndLocation)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline,
bool isExplicitSpecified, bool isConstexpr,
SourceLocation EndLocation)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation) {
IsExplicitSpecified = isExplicitSpecified;
}
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@ -2452,17 +2518,12 @@ class CXXConversionDecl : public CXXMethodDecl {
SourceLocation EndLocation);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Whether this conversion function declaration is marked
/// "explicit", meaning that it can only be used for direct initialization
/// (including explitly written casts). This is a C++11 feature.
/// Whether this function is marked as explicit explicitly.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
/// \brief Whether this is an explicit conversion operator (C++11 and later).
///
/// Explicit conversion operators are only considered for direct
/// initialization, e.g., when the user has explicitly written a cast.
/// Whether this function is explicit.
bool isExplicit() const {
return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
return getCanonicalDecl()->isExplicitSpecified();
}
/// \brief Returns the type that this conversion function is converting to.
@ -2474,6 +2535,13 @@ class CXXConversionDecl : public CXXMethodDecl {
/// a lambda closure type to a block pointer.
bool isLambdaToBlockPointerConversion() const;
CXXConversionDecl *getCanonicalDecl() override {
return cast<CXXConversionDecl>(FunctionDecl::getCanonicalDecl());
}
const CXXConversionDecl *getCanonicalDecl() const {
return const_cast<CXXConversionDecl*>(this)->getCanonicalDecl();
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == CXXConversion; }

View File

@ -131,7 +131,7 @@ struct StoredDeclsList {
} else {
DeclsTy &Vec = *getAsVector();
Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
std::mem_fun(&Decl::isFromASTFile)),
[](Decl *D) { return D->isFromASTFile(); }),
Vec.end());
// Don't have any external decls any more.
Data = DeclsAndHasExternalTy(&Vec, false);

View File

@ -381,15 +381,17 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ArrayRef<SourceLocation> SelLocs = llvm::None);
// Iterator access to parameter types.
typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
param_type_iterator;
struct GetTypeFn {
QualType operator()(const ParmVarDecl *PD) const { return PD->getType(); }
};
typedef llvm::mapped_iterator<param_const_iterator, GetTypeFn>
param_type_iterator;
param_type_iterator param_type_begin() const {
return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
return llvm::map_iterator(param_begin(), GetTypeFn());
}
param_type_iterator param_type_end() const {
return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
return llvm::map_iterator(param_end(), GetTypeFn());
}
/// createImplicitParams - Used to lazily create the self and cmd
@ -743,6 +745,8 @@ class ObjCPropertyDecl : public NamedDecl {
Selector GetterName; // getter name of NULL if no getter
Selector SetterName; // setter name of NULL if no setter
SourceLocation GetterNameLoc; // location of the getter attribute's value
SourceLocation SetterNameLoc; // location of the setter attribute's value
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
@ -855,10 +859,18 @@ class ObjCPropertyDecl : public NamedDecl {
}
Selector getGetterName() const { return GetterName; }
void setGetterName(Selector Sel) { GetterName = Sel; }
SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
GetterName = Sel;
GetterNameLoc = Loc;
}
Selector getSetterName() const { return SetterName; }
void setSetterName(Selector Sel) { SetterName = Sel; }
SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
SetterName = Sel;
SetterNameLoc = Loc;
}
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
@ -2320,11 +2332,9 @@ class ObjCImplDecl : public ObjCContainerDecl {
protected:
ObjCImplDecl(Kind DK, DeclContext *DC,
ObjCInterfaceDecl *classInterface,
IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc)
: ObjCContainerDecl(DK, DC,
classInterface? classInterface->getIdentifier()
: nullptr,
nameLoc, atStartLoc),
: ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
ClassInterface(classInterface) {}
public:
@ -2386,9 +2396,6 @@ class ObjCImplDecl : public ObjCContainerDecl {
class ObjCCategoryImplDecl : public ObjCImplDecl {
void anchor() override;
// Category name
IdentifierInfo *Id;
// Category name location
SourceLocation CategoryNameLoc;
@ -2396,8 +2403,9 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
ObjCInterfaceDecl *classInterface,
SourceLocation nameLoc, SourceLocation atStartLoc,
SourceLocation CategoryNameLoc)
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
Id(Id), CategoryNameLoc(CategoryNameLoc) {}
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
nameLoc, atStartLoc),
CategoryNameLoc(CategoryNameLoc) {}
public:
static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
@ -2407,37 +2415,10 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
SourceLocation CategoryNameLoc);
static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// getIdentifier - Get the identifier that names the category
/// interface associated with this implementation.
/// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
/// with a different meaning. For example:
/// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
/// returns the class interface name, whereas
/// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
/// returns the category name.
IdentifierInfo *getIdentifier() const {
return Id;
}
void setIdentifier(IdentifierInfo *II) { Id = II; }
ObjCCategoryDecl *getCategoryDecl() const;
SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
/// getName - Get the name of identifier for the class interface associated
/// with this implementation as a StringRef.
//
// FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
// meaning.
StringRef getName() const { return Id ? Id->getName() : StringRef(); }
/// @brief Get the name of the class associated with this interface.
//
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const {
return getName();
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
@ -2493,7 +2474,10 @@ class ObjCImplementationDecl : public ObjCImplDecl {
SourceLocation superLoc = SourceLocation(),
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation())
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
: ObjCImplDecl(ObjCImplementation, DC, classInterface,
classInterface ? classInterface->getIdentifier()
: nullptr,
nameLoc, atStartLoc),
SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
IvarRBraceLoc(IvarRBraceLoc),
IvarInitializers(nullptr), NumIvarInitializers(0),

View File

@ -344,6 +344,32 @@ class DefaultArgStorage {
// Kinds of Templates
//===----------------------------------------------------------------------===//
/// \brief Stores the template parameter list and associated constraints for
/// \c TemplateDecl objects that track associated constraints.
class ConstrainedTemplateDeclInfo {
friend TemplateDecl;
public:
ConstrainedTemplateDeclInfo() : TemplateParams(), AssociatedConstraints() {}
TemplateParameterList *getTemplateParameters() const {
return TemplateParams;
}
Expr *getAssociatedConstraints() const { return AssociatedConstraints; }
protected:
void setTemplateParameters(TemplateParameterList *TParams) {
TemplateParams = TParams;
}
void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
TemplateParameterList *TemplateParams;
Expr *AssociatedConstraints;
};
/// \brief The base class of all kinds of template declarations (e.g.,
/// class, function, etc.).
///
@ -352,33 +378,53 @@ class DefaultArgStorage {
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, 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,
// Used when there is no templated element (e.g., for tt-params).
TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params)
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
TemplateParams(Params) {}
TemplateParams(CTDI) {
this->setTemplateParameters(Params);
}
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params)
: TemplateDecl(nullptr, DK, DC, L, Name, Params) {}
// Construct a template decl with name, parameters, and templated element.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false),
TemplateParams(Params) {}
TemplateParams(CTDI) {
this->setTemplateParameters(Params);
}
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: TemplateDecl(nullptr, DK, DC, L, Name, Params, Decl) {}
public:
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
return TemplateParams;
const auto *const CTDI =
TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
return CTDI ? CTDI->getTemplateParameters()
: TemplateParams.get<TemplateParameterList *>();
}
/// Get the constraint-expression from the associated requires-clause (if any)
const Expr *getRequiresClause() const {
return TemplateParams ? TemplateParams->getRequiresClause() : nullptr;
const TemplateParameterList *const TP = getTemplateParameters();
return TP ? TP->getRequiresClause() : nullptr;
}
Expr *getAssociatedConstraints() const {
const TemplateDecl *const C = cast<TemplateDecl>(getCanonicalDecl());
const auto *const CTDI =
C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
}
/// Get the underlying, templated declaration.
@ -391,7 +437,7 @@ class TemplateDecl : public NamedDecl {
}
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(TemplateParams->getTemplateLoc(),
return SourceRange(getTemplateParameters()->getTemplateLoc(),
TemplatedDecl.getPointer()->getSourceRange().getEnd());
}
@ -407,7 +453,29 @@ class TemplateDecl : public NamedDecl {
/// (function or variable) is a concept.
llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl;
TemplateParameterList* TemplateParams;
/// \brief The template parameter list and optional requires-clause
/// associated with this declaration; alternatively, a
/// \c ConstrainedTemplateDeclInfo if the associated constraints of the
/// template are being tracked by this particular declaration.
llvm::PointerUnion<TemplateParameterList *,
ConstrainedTemplateDeclInfo *>
TemplateParams;
void setTemplateParameters(TemplateParameterList *TParams) {
if (auto *const CTDI =
TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>()) {
CTDI->setTemplateParameters(TParams);
} else {
TemplateParams = TParams;
}
}
void setAssociatedConstraints(Expr *AC) {
assert(isCanonicalDecl() &&
"Attaching associated constraints to non-canonical Decl");
TemplateParams.get<ConstrainedTemplateDeclInfo *>()
->setAssociatedConstraints(AC);
}
public:
/// \brief Initialize the underlying templated declaration and
@ -737,11 +805,17 @@ class RedeclarableTemplateDecl : public TemplateDecl,
virtual CommonBase *newCommon(ASTContext &C) const = 0;
// Construct a template decl with name, parameters, and templated element.
RedeclarableTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK,
ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
NamedDecl *Decl)
: TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C),
Common() {}
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
Common() {}
: RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
public:
template <class decl_type> friend class RedeclarableTemplate;
@ -863,8 +937,6 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> {
/// Declaration of a template function.
class FunctionTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
/// \brief Data that is common to all of the declarations of a given
/// function template.
@ -1407,7 +1479,9 @@ class TemplateTemplateParmDecl final
unsigned NumExpansions);
using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
using TemplateParmPosition::getPosition;
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
/// \brief Whether this template template parameter is a template
@ -1960,8 +2034,6 @@ class ClassTemplatePartialSpecializationDecl
/// Declaration of a class template.
class ClassTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
/// \brief Data that is common to all of the declarations of a given
/// class template.
@ -1997,10 +2069,16 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
ClassTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, ASTContext &C,
DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(CTDI, ClassTemplate, C, DC, L, Name, Params,
Decl) {}
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
NamedDecl *Decl)
: RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
: ClassTemplateDecl(nullptr, C, DC, L, Name, Params, Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
@ -2023,12 +2101,14 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
return getTemplatedDecl()->isThisDeclarationADefinition();
}
// FIXME: remove default argument for AssociatedConstraints
/// \brief Create a class template node.
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
NamedDecl *Decl,
Expr *AssociatedConstraints = nullptr);
/// \brief Create an empty class template node.
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@ -2247,8 +2327,6 @@ class FriendTemplateDecl : public Decl {
/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
/// \endcode
class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
typedef CommonBase Common;
@ -2773,8 +2851,6 @@ class VarTemplatePartialSpecializationDecl
/// Declaration of a variable template.
class VarTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
/// \brief Data that is common to all of the declarations of a given
/// variable template.
@ -2946,6 +3022,16 @@ inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
return P.get<TemplateTemplateParmDecl*>();
}
inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
auto *TD = dyn_cast<TemplateDecl>(D);
return TD && (isa<ClassTemplateDecl>(TD) ||
isa<ClassTemplatePartialSpecializationDecl>(TD) ||
isa<TypeAliasTemplateDecl>(TD) ||
isa<TemplateTemplateParmDecl>(TD))
? TD
: nullptr;
}
} /* end of namespace clang */
#endif

View File

@ -23,6 +23,7 @@ namespace llvm {
namespace clang {
class ASTContext;
class CXXDeductionGuideNameExtra;
class CXXLiteralOperatorIdName;
class CXXOperatorIdName;
class CXXSpecialName;
@ -32,6 +33,7 @@ namespace clang {
enum OverloadedOperatorKind : int;
struct PrintingPolicy;
class QualType;
class TemplateDecl;
class Type;
class TypeSourceInfo;
class UsingDirectiveDecl;
@ -56,6 +58,7 @@ class DeclarationName {
CXXConstructorName,
CXXDestructorName,
CXXConversionFunctionName,
CXXDeductionGuideName,
CXXOperatorName,
CXXLiteralOperatorName,
CXXUsingDirective
@ -118,42 +121,36 @@ class DeclarationName {
CXXSpecialName *getAsCXXSpecialName() const {
NameKind Kind = getNameKind();
if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
return reinterpret_cast<CXXSpecialName *>(getExtra());
return nullptr;
}
/// If the stored pointer is actually a CXXDeductionGuideNameExtra, returns a
/// pointer to it. Otherwise, returns a NULL pointer.
CXXDeductionGuideNameExtra *getAsCXXDeductionGuideNameExtra() const {
if (getNameKind() == CXXDeductionGuideName)
return reinterpret_cast<CXXDeductionGuideNameExtra *>(getExtra());
return nullptr;
}
/// getAsCXXOperatorIdName
CXXOperatorIdName *getAsCXXOperatorIdName() const {
if (getNameKind() == CXXOperatorName)
return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
return reinterpret_cast<CXXOperatorIdName *>(getExtra());
return nullptr;
}
CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
if (getNameKind() == CXXLiteralOperatorName)
return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
return reinterpret_cast<CXXLiteralOperatorIdName *>(getExtra());
return nullptr;
}
// Construct a declaration name from the name of a C++ constructor,
// destructor, or conversion function.
DeclarationName(CXXSpecialName *Name)
DeclarationName(DeclarationNameExtra *Name)
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
Ptr |= StoredDeclarationNameExtra;
}
// Construct a declaration name from the name of a C++ overloaded
// operator.
DeclarationName(CXXOperatorIdName *Name)
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
Ptr |= StoredDeclarationNameExtra;
}
DeclarationName(CXXLiteralOperatorIdName *Name)
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
Ptr |= StoredDeclarationNameExtra;
}
@ -252,6 +249,10 @@ class DeclarationName {
/// type associated with that name.
QualType getCXXNameType() const;
/// If this name is the name of a C++ deduction guide, return the
/// template associated with that name.
TemplateDecl *getCXXDeductionGuideTemplate() const;
/// getCXXOverloadedOperator - If this name is the name of an
/// overloadable operator in C++ (e.g., @c operator+), retrieve the
/// kind of overloaded operator.
@ -346,6 +347,7 @@ class DeclarationNameTable {
void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
CXXOperatorIdName *CXXOperatorNames; // Operator names
void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
void *CXXDeductionGuideNames; // FoldingSet<CXXDeductionGuideNameExtra> *
DeclarationNameTable(const DeclarationNameTable&) = delete;
void operator=(const DeclarationNameTable&) = delete;
@ -368,6 +370,9 @@ class DeclarationNameTable {
/// for the given Type.
DeclarationName getCXXDestructorName(CanQualType Ty);
/// Returns the name of a C++ deduction guide for the given template.
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD);
/// getCXXConversionFunctionName - Returns the name of a C++
/// conversion function for the given Type.
DeclarationName getCXXConversionFunctionName(CanQualType Ty);

View File

@ -115,6 +115,7 @@ class Expr : public Stmt {
ExprBits.InstantiationDependent = ID;
ExprBits.ValueKind = VK;
ExprBits.ObjectKind = OK;
assert(ExprBits.ObjectKind == OK && "truncated kind");
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
setType(T);
}
@ -907,6 +908,10 @@ class OpaqueValueExpr : public Expr {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
/// The source expression of an opaque value expression is the
/// expression which originally generated the value. This is
/// provided as a convenience for analyses that don't wish to
@ -1167,6 +1172,10 @@ class DeclRefExpr final
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
friend TrailingObjects;
friend class ASTStmtReader;
friend class ASTStmtWriter;
@ -1222,6 +1231,9 @@ class PredefinedExpr : public Expr {
// Iterators
child_range children() { return child_range(&FnName, &FnName + 1); }
const_child_range children() const {
return const_child_range(&FnName, &FnName + 1);
}
friend class ASTStmtReader;
};
@ -1315,6 +1327,9 @@ class IntegerLiteral : public Expr, public APIntStorage {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
class CharacterLiteral : public Expr {
@ -1365,6 +1380,9 @@ class CharacterLiteral : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
class FloatingLiteral : public Expr, private APFloatStorage {
@ -1429,6 +1447,9 @@ class FloatingLiteral : public Expr, private APFloatStorage {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
/// ImaginaryLiteral - We support imaginary integer and floating point literals,
@ -1461,6 +1482,9 @@ class ImaginaryLiteral : public Expr {
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
};
/// StringLiteral - This represents a string literal expression, e.g. "foo"
@ -1628,6 +1652,9 @@ class StringLiteral : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
@ -1669,6 +1696,9 @@ class ParenExpr : public Expr {
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
};
/// UnaryOperator - This represents the unary-expression's (except sizeof and
@ -1778,6 +1808,9 @@ class UnaryOperator : public Expr {
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
};
/// Helper class for OffsetOfExpr.
@ -1981,6 +2014,11 @@ class OffsetOfExpr final
Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
return child_range(begin, begin + NumExprs);
}
const_child_range children() const {
Stmt *const *begin =
reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
return const_child_range(begin, begin + NumExprs);
}
friend TrailingObjects;
};
@ -2069,6 +2107,7 @@ class UnaryExprOrTypeTraitExpr : public Expr {
// Iterators
child_range children();
const_child_range children() const;
};
//===----------------------------------------------------------------------===//
@ -2153,6 +2192,9 @@ class ArraySubscriptExpr : public Expr {
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
const_child_range children() const {
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
};
/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
@ -2313,6 +2355,11 @@ class CallExpr : public Expr {
return child_range(&SubExprs[0],
&SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
}
const_child_range children() const {
return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
getNumPreArgs() + PREARGS_START);
}
};
/// Extra data stored in some MemberExpr objects.
@ -2567,6 +2614,9 @@ class MemberExpr final
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
const_child_range children() const {
return const_child_range(&Base, &Base + 1);
}
friend TrailingObjects;
friend class ASTReader;
@ -2639,6 +2689,9 @@ class CompoundLiteralExpr : public Expr {
// Iterators
child_range children() { return child_range(&Init, &Init+1); }
const_child_range children() const {
return const_child_range(&Init, &Init + 1);
}
};
/// CastExpr - Base class for type casts, including both implicit
@ -2725,6 +2778,7 @@ class CastExpr : public Expr {
// Iterators
child_range children() { return child_range(&Op, &Op+1); }
const_child_range children() const { return const_child_range(&Op, &Op + 1); }
};
/// ImplicitCastExpr - Allows us to explicitly represent implicit type
@ -2917,11 +2971,9 @@ class BinaryOperator : public Expr {
private:
unsigned Opc : 6;
// Records the FP_CONTRACT pragma status at the point that this binary
// operator was parsed. This bit is only meaningful for operations on
// floating point types. For all other types it should default to
// false.
unsigned FPContractable : 1;
// This is only meaningful for operations on floating point types and 0
// otherwise.
unsigned FPFeatures : 2;
SourceLocation OpLoc;
enum { LHS, RHS, END_EXPR };
@ -2930,7 +2982,7 @@ class BinaryOperator : public Expr {
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation opLoc, bool fpContractable)
SourceLocation opLoc, FPOptions FPFeatures)
: Expr(BinaryOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
@ -2938,7 +2990,7 @@ class BinaryOperator : public Expr {
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
@ -3070,19 +3122,26 @@ class BinaryOperator : public Expr {
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
const_child_range children() const {
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
void setFPContractable(bool FPC) { FPContractable = FPC; }
void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); }
FPOptions getFPFeatures() const { return FPOptions(FPFeatures); }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractable() const { return FPContractable; }
bool isFPContractableWithinStatement() const {
return FPOptions(FPFeatures).allowFPContractWithinStatement();
}
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation opLoc, bool fpContractable, bool dead2)
SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
@ -3090,7 +3149,7 @@ class BinaryOperator : public Expr {
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
}
@ -3112,8 +3171,8 @@ class CompoundAssignOperator : public BinaryOperator {
CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
ExprValueKind VK, ExprObjectKind OK,
QualType CompLHSType, QualType CompResultType,
SourceLocation OpLoc, bool fpContractable)
: BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
SourceLocation OpLoc, FPOptions FPFeatures)
: BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
true),
ComputationLHSType(CompLHSType),
ComputationResultType(CompResultType) {
@ -3246,6 +3305,9 @@ class ConditionalOperator : public AbstractConditionalOperator {
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
const_child_range children() const {
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
};
/// BinaryConditionalOperator - The GNU extension to the conditional
@ -3331,6 +3393,9 @@ class BinaryConditionalOperator : public AbstractConditionalOperator {
child_range children() {
return child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
}
const_child_range children() const {
return const_child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
}
};
inline Expr *AbstractConditionalOperator::getCond() const {
@ -3385,6 +3450,9 @@ class AddrLabelExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
@ -3427,6 +3495,9 @@ class StmtExpr : public Expr {
// Iterators
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
const_child_range children() const {
return const_child_range(&SubStmt, &SubStmt + 1);
}
};
/// ShuffleVectorExpr - clang-specific builtin-in function
@ -3495,6 +3566,9 @@ class ShuffleVectorExpr : public Expr {
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
}
const_child_range children() const {
return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs);
}
};
/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
@ -3549,6 +3623,9 @@ class ConvertVectorExpr : public Expr {
// Iterators
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
const_child_range children() const {
return const_child_range(&SrcExpr, &SrcExpr + 1);
}
};
/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
@ -3629,6 +3706,9 @@ class ChooseExpr : public Expr {
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
const_child_range children() const {
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
};
/// GNUNullExpr - Implements the GNU __null extension, which is a name
@ -3665,6 +3745,9 @@ class GNUNullExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
/// Represents a call to the builtin function \c __builtin_va_arg.
@ -3712,6 +3795,9 @@ class VAArgExpr : public Expr {
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}
};
/// @brief Describes an C or C++ initializer list.
@ -3936,10 +4022,16 @@ class InitListExpr : public Expr {
// Iterators
child_range children() {
const_child_range CCR = const_cast<const InitListExpr *>(this)->children();
return child_range(cast_away_const(CCR.begin()),
cast_away_const(CCR.end()));
}
const_child_range children() const {
// FIXME: This does not include the array filler expression.
if (InitExprs.empty())
return child_range(child_iterator(), child_iterator());
return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
return const_child_range(const_child_iterator(), const_child_iterator());
return const_child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
}
typedef InitExprsTy::iterator iterator;
@ -4254,6 +4346,10 @@ class DesignatedInitExpr final
Stmt **begin = getTrailingObjects<Stmt *>();
return child_range(begin, begin + NumSubExprs);
}
const_child_range children() const {
Stmt * const *begin = getTrailingObjects<Stmt *>();
return const_child_range(begin, begin + NumSubExprs);
}
friend TrailingObjects;
};
@ -4287,6 +4383,9 @@ class NoInitExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
// In cases like:
@ -4332,6 +4431,10 @@ class DesignatedInitUpdateExpr : public Expr {
child_range children() {
return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
}
const_child_range children() const {
return const_child_range(&BaseAndUpdaterExprs[0],
&BaseAndUpdaterExprs[0] + 2);
}
};
/// \brief Represents a loop initializing the elements of an array.
@ -4393,6 +4496,9 @@ class ArrayInitLoopExpr : public Expr {
child_range children() {
return child_range(SubExprs, SubExprs + 2);
}
const_child_range children() const {
return const_child_range(SubExprs, SubExprs + 2);
}
friend class ASTReader;
friend class ASTStmtReader;
@ -4421,6 +4527,9 @@ class ArrayInitIndexExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
friend class ASTReader;
friend class ASTStmtReader;
@ -4455,6 +4564,9 @@ class ImplicitValueInitExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
class ParenListExpr : public Expr {
@ -4501,6 +4613,9 @@ class ParenListExpr : public Expr {
child_range children() {
return child_range(&Exprs[0], &Exprs[0]+NumExprs);
}
const_child_range children() const {
return const_child_range(&Exprs[0], &Exprs[0] + NumExprs);
}
friend class ASTStmtReader;
friend class ASTStmtWriter;
@ -4621,7 +4736,9 @@ class GenericSelectionExpr : public Expr {
child_range children() {
return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
}
const_child_range children() const {
return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs);
}
friend class ASTStmtReader;
};
@ -4690,6 +4807,9 @@ class ExtVectorElementExpr : public Expr {
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
const_child_range children() const {
return const_child_range(&Base, &Base + 1);
}
};
/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
@ -4731,6 +4851,9 @@ class BlockExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
@ -4776,6 +4899,9 @@ class AsTypeExpr : public Expr {
// Iterators
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
const_child_range children() const {
return const_child_range(&SrcExpr, &SrcExpr + 1);
}
};
/// PseudoObjectExpr - An expression which accesses a pseudo-object
@ -4914,8 +5040,15 @@ class PseudoObjectExpr final
}
child_range children() {
Stmt **cs = reinterpret_cast<Stmt**>(getSubExprsBuffer());
return child_range(cs, cs + getNumSubExprs());
const_child_range CCR =
const_cast<const PseudoObjectExpr *>(this)->children();
return child_range(cast_away_const(CCR.begin()),
cast_away_const(CCR.end()));
}
const_child_range children() const {
Stmt *const *cs = const_cast<Stmt *const *>(
reinterpret_cast<const Stmt *const *>(getSubExprsBuffer()));
return const_child_range(cs, cs + getNumSubExprs());
}
static bool classof(const Stmt *T) {
@ -5021,6 +5154,9 @@ class AtomicExpr : public Expr {
child_range children() {
return child_range(SubExprs, SubExprs+NumSubExprs);
}
const_child_range children() const {
return const_child_range(SubExprs, SubExprs + NumSubExprs);
}
};
/// TypoExpr - Internal placeholder for expressions where typo correction
@ -5039,6 +5175,10 @@ class TypoExpr : public Expr {
child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }

View File

@ -54,18 +54,16 @@ class CXXOperatorCallExpr : public CallExpr {
OverloadedOperatorKind Operator;
SourceRange Range;
// Record the FP_CONTRACT state that applies to this operator call. Only
// meaningful for floating point types. For other types this value can be
// set to false.
unsigned FPContractable : 1;
// Only meaningful for floating point types.
FPOptions FPFeatures;
SourceRange getSourceRangeImpl() const LLVM_READONLY;
public:
CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
SourceLocation operatorloc, bool fpContractable)
SourceLocation operatorloc, FPOptions FPFeatures)
: CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
Operator(Op), FPContractable(fpContractable) {
Operator(Op), FPFeatures(FPFeatures) {
Range = getSourceRangeImpl();
}
explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
@ -113,11 +111,15 @@ class CXXOperatorCallExpr : public CallExpr {
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
void setFPContractable(bool FPC) { FPContractable = FPC; }
void setFPFeatures(FPOptions F) { FPFeatures = F; }
FPOptions getFPFeatures() const { return FPFeatures; }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractable() const { return FPContractable; }
bool isFPContractableWithinStatement() const {
return FPFeatures.allowFPContractWithinStatement();
}
friend class ASTStmtReader;
friend class ASTStmtWriter;
@ -1470,7 +1472,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
public:
CXXTemporaryObjectExpr(const ASTContext &C,
CXXConstructorDecl *Cons,
TypeSourceInfo *Type,
QualType Type,
TypeSourceInfo *TSI,
ArrayRef<Expr *> Args,
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
@ -4122,16 +4125,18 @@ class CoroutineSuspendExpr : public Expr {
enum SubExpr { Common, Ready, Suspend, Resume, Count };
Stmt *SubExprs[SubExpr::Count];
OpaqueValueExpr *OpaqueValue = nullptr;
friend class ASTStmtReader;
public:
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
Expr *Ready, Expr *Suspend, Expr *Resume)
Expr *Ready, Expr *Suspend, Expr *Resume,
OpaqueValueExpr *OpaqueValue)
: Expr(SC, Resume->getType(), Resume->getValueKind(),
Resume->getObjectKind(), Resume->isTypeDependent(),
Resume->isValueDependent(), Common->isInstantiationDependent(),
Common->containsUnexpandedParameterPack()),
KeywordLoc(KeywordLoc) {
KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = Ready;
SubExprs[SubExpr::Suspend] = Suspend;
@ -4160,6 +4165,8 @@ class CoroutineSuspendExpr : public Expr {
Expr *getCommonExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Common]);
}
/// \brief getOpaqueValue - Return the opaque value placeholder.
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
Expr *getReadyExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
@ -4193,11 +4200,17 @@ class CoawaitExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
public:
CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
Expr *Suspend, Expr *Resume)
Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
bool IsImplicit = false)
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
Suspend, Resume) {}
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand)
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {}
Suspend, Resume, OpaqueValue) {
CoawaitBits.IsImplicit = IsImplicit;
}
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
bool IsImplicit = false)
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
CoawaitBits.IsImplicit = IsImplicit;
}
CoawaitExpr(EmptyShell Empty)
: CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
@ -4206,19 +4219,67 @@ class CoawaitExpr : public CoroutineSuspendExpr {
return getCommonExpr();
}
bool isImplicit() const { return CoawaitBits.IsImplicit; }
void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoawaitExprClass;
}
};
/// \brief Represents a 'co_await' expression while the type of the promise
/// is dependent.
class DependentCoawaitExpr : public Expr {
SourceLocation KeywordLoc;
Stmt *SubExprs[2];
friend class ASTStmtReader;
public:
DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
UnresolvedLookupExpr *OpCoawait)
: Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary,
/*TypeDependent*/ true, /*ValueDependent*/ true,
/*InstantiationDependent*/ true,
Op->containsUnexpandedParameterPack()),
KeywordLoc(KeywordLoc) {
// NOTE: A co_await expression is dependent on the coroutines promise
// type and may be dependent even when the `Op` expression is not.
assert(Ty->isDependentType() &&
"wrong constructor for non-dependent co_await/co_yield expression");
SubExprs[0] = Op;
SubExprs[1] = OpCoawait;
}
DependentCoawaitExpr(EmptyShell Empty)
: Expr(DependentCoawaitExprClass, Empty) {}
Expr *getOperand() const { return cast<Expr>(SubExprs[0]); }
UnresolvedLookupExpr *getOperatorCoawaitLookup() const {
return cast<UnresolvedLookupExpr>(SubExprs[1]);
}
SourceLocation getKeywordLoc() const { return KeywordLoc; }
SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
return getOperand()->getLocEnd();
}
child_range children() { return child_range(SubExprs, SubExprs + 2); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == DependentCoawaitExprClass;
}
};
/// \brief Represents a 'co_yield' expression.
class CoyieldExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
public:
CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
Expr *Suspend, Expr *Resume)
Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
: CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
Suspend, Resume) {}
Suspend, Resume, OpaqueValue) {}
CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
: CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
CoyieldExpr(EmptyShell Empty)

View File

@ -0,0 +1,51 @@
//===--- ExternalASTMerger.h - Merging External AST Interface ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the ExternalASTMerger, which vends a combination of ASTs
// from several different ASTContext/FileManager pairs
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_EXTERNALASTMERGER_H
#define LLVM_CLANG_AST_EXTERNALASTMERGER_H
#include "clang/AST/ASTImporter.h"
#include "clang/AST/ExternalASTSource.h"
namespace clang {
class ExternalASTMerger : public ExternalASTSource {
public:
struct ImporterPair {
std::unique_ptr<ASTImporter> Forward;
std::unique_ptr<ASTImporter> Reverse;
};
private:
std::vector<ImporterPair> Importers;
public:
struct ImporterEndpoint {
ASTContext &AST;
FileManager &FM;
};
ExternalASTMerger(const ImporterEndpoint &Target,
llvm::ArrayRef<ImporterEndpoint> Sources);
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
void
FindExternalLexicalDecls(const DeclContext *DC,
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) override;
};
} // end namespace clang
#endif

View File

@ -16,6 +16,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclBase.h"
#include "clang/Basic/Module.h"
#include "llvm/ADT/DenseMap.h"
namespace clang {
@ -149,26 +150,30 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
StringRef PCHModuleName;
StringRef Path;
StringRef ASTFile;
uint64_t Signature = 0;
ASTFileSignature Signature;
const Module *ClangModule = nullptr;
public:
ASTSourceDescriptor(){};
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
uint64_t Signature)
ASTFileSignature Signature)
: PCHModuleName(std::move(Name)), Path(std::move(Path)),
ASTFile(std::move(ASTFile)), Signature(Signature){};
ASTSourceDescriptor(const Module &M);
std::string getModuleName() const;
StringRef getPath() const { return Path; }
StringRef getASTFile() const { return ASTFile; }
uint64_t getSignature() const { return Signature; }
ASTFileSignature getSignature() const { return Signature; }
const Module *getModuleOrNull() const { return ClangModule; }
};
/// Return a descriptor for the corresponding module, if one exists.
virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy };
virtual ExtKind hasExternalDefinitions(const Decl *D);
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
///

View File

@ -0,0 +1,84 @@
//===-- ODRHash.h - Hashing to diagnose ODR failures ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the declaration of the ODRHash class, which calculates
/// a hash based on AST nodes, which is stable across different runs.
///
//===----------------------------------------------------------------------===//
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
class Decl;
class IdentifierInfo;
class NestedNameSpecifer;
class Stmt;
class TemplateParameterList;
// ODRHash is used to calculate a hash based on AST node contents that
// does not rely on pointer addresses. This allows the hash to not vary
// between runs and is usable to detect ODR problems in modules. To use,
// construct an ODRHash object, then call Add* methods over the nodes that
// need to be hashed. Then call CalculateHash to get the hash value.
// Typically, only one Add* call is needed. clear can be called to reuse the
// object.
class ODRHash {
// Use DenseMaps to convert between Decl and Type pointers and an index value.
llvm::DenseMap<const Decl*, unsigned> DeclMap;
llvm::DenseMap<const Type*, unsigned> TypeMap;
// Save space by processing bools at the end.
llvm::SmallVector<bool, 128> Bools;
llvm::FoldingSetNodeID ID;
public:
ODRHash() {}
// Use this for ODR checking classes between modules. This method compares
// more information than the AddDecl class.
void AddCXXRecordDecl(const CXXRecordDecl *Record);
// Process SubDecls of the main Decl. This method calls the DeclVisitor
// while AddDecl does not.
void AddSubDecl(const Decl *D);
// Reset the object for reuse.
void clear();
// Add booleans to ID and uses it to calculate the hash.
unsigned CalculateHash();
// Add AST nodes that need to be processed.
void AddDecl(const Decl *D);
void AddType(const Type *T);
void AddQualType(QualType T);
void AddStmt(const Stmt *S);
void AddIdentifierInfo(const IdentifierInfo *II);
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
void AddTemplateName(TemplateName Name);
void AddDeclarationName(DeclarationName Name);
void AddTemplateArgument(TemplateArgument TA);
void AddTemplateParameterList(const TemplateParameterList *TPL);
// Save booleans until the end to lower the size of data to process.
void AddBoolean(bool value);
static bool isWhitelistedDecl(const Decl* D, const CXXRecordDecl *Record);
};
} // end namespace clang

View File

@ -76,10 +76,17 @@ class OMPClauseWithPreInit {
friend class OMPClauseReader;
/// Pre-initialization statement for the clause.
Stmt *PreInit;
/// Region that captures the associated stmt.
OpenMPDirectiveKind CaptureRegion;
protected:
/// Set pre-initialization statement for the clause.
void setPreInitStmt(Stmt *S) { PreInit = S; }
OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) {
void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) {
PreInit = S;
CaptureRegion = ThisRegion;
}
OMPClauseWithPreInit(const OMPClause *This)
: PreInit(nullptr), CaptureRegion(OMPD_unknown) {
assert(get(This) && "get is not tuned for pre-init.");
}
@ -88,6 +95,8 @@ class OMPClauseWithPreInit {
const Stmt *getPreInitStmt() const { return PreInit; }
/// Get pre-initialization statement for the clause.
Stmt *getPreInitStmt() { return PreInit; }
/// Get capture region for the stmt in the clause.
OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; }
static OMPClauseWithPreInit *get(OMPClause *C);
static const OMPClauseWithPreInit *get(const OMPClause *C);
};
@ -194,7 +203,7 @@ template <class T> class OMPVarListClause : public OMPClause {
/// In this example directive '#pragma omp parallel' has simple 'if' clause with
/// condition 'a > 5' and directive name modifier 'parallel'.
///
class OMPIfClause : public OMPClause {
class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// \brief Location of '('.
SourceLocation LParenLoc;
@ -225,26 +234,31 @@ class OMPIfClause : public OMPClause {
///
/// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
/// \param Cond Condition of the clause.
/// \param HelperCond Helper condition for the clause.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param NameModifierLoc Location of directive name modifier.
/// \param ColonLoc [OpenMP 4.1] Location of ':'.
/// \param EndLoc Ending location of the clause.
///
OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation NameModifierLoc, SourceLocation ColonLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
NameModifierLoc(NameModifierLoc) {}
OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation NameModifierLoc,
SourceLocation ColonLoc, SourceLocation EndLoc)
: OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this),
LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc),
NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// \brief Build an empty clause.
///
OMPIfClause()
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
NameModifierLoc() {}
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this), LParenLoc(), Condition(nullptr), ColonLoc(),
NameModifier(OMPD_unknown), NameModifierLoc() {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@ -331,7 +345,7 @@ class OMPFinalClause : public OMPClause {
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
/// clause with number of threads '6'.
///
class OMPNumThreadsClause : public OMPClause {
class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// \brief Location of '('.
SourceLocation LParenLoc;
@ -346,20 +360,29 @@ class OMPNumThreadsClause : public OMPClause {
/// \brief Build 'num_threads' clause with condition \a NumThreads.
///
/// \param NumThreads Number of threads for the construct.
/// \param HelperNumThreads Helper Number of threads for the construct.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
///
OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumThreads(NumThreads) {}
OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads,
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_num_threads, StartLoc, EndLoc),
OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
NumThreads(NumThreads) {
setPreInitStmt(HelperNumThreads, CaptureRegion);
}
/// \brief Build an empty clause.
///
OMPNumThreadsClause()
: OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
LParenLoc(SourceLocation()), NumThreads(nullptr) {}
OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
NumThreads(nullptr) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@ -3456,7 +3479,7 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// In this example directive '#pragma omp teams' has clause 'num_teams'
/// with single expression 'n'.
///
class OMPNumTeamsClause : public OMPClause {
class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// \brief Location of '('.
SourceLocation LParenLoc;
@ -3472,20 +3495,27 @@ class OMPNumTeamsClause : public OMPClause {
/// \brief Build 'num_teams' clause.
///
/// \param E Expression associated with this clause.
/// \param HelperE Helper Expression associated with this clause.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
///
OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumTeams(E) {}
: OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this),
LParenLoc(LParenLoc), NumTeams(E) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// \brief Build an empty clause.
///
OMPNumTeamsClause()
: OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
LParenLoc(SourceLocation()), NumTeams(nullptr) {}
: OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
NumTeams(nullptr) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
/// \brief Returns the location of '('.
@ -3511,7 +3541,7 @@ class OMPNumTeamsClause : public OMPClause {
/// In this example directive '#pragma omp teams' has clause 'thread_limit'
/// with single expression 'n'.
///
class OMPThreadLimitClause : public OMPClause {
class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// \brief Location of '('.
SourceLocation LParenLoc;
@ -3527,20 +3557,28 @@ class OMPThreadLimitClause : public OMPClause {
/// \brief Build 'thread_limit' clause.
///
/// \param E Expression associated with this clause.
/// \param HelperE Helper Expression associated with this clause.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
///
OMPThreadLimitClause(Expr *E, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc),
ThreadLimit(E) {}
OMPThreadLimitClause(Expr *E, Stmt *HelperE,
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_thread_limit, StartLoc, EndLoc),
OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// \brief Build an empty clause.
///
OMPThreadLimitClause()
: OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
LParenLoc(SourceLocation()), ThreadLimit(nullptr) {}
OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
ThreadLimit(nullptr) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
/// \brief Returns the location of '('.

View File

@ -774,6 +774,11 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
break;
case DeclarationName::CXXDeductionGuideName:
TRY_TO(TraverseTemplateName(
TemplateName(NameInfo.getName().getCXXDeductionGuideTemplate())));
break;
case DeclarationName::Identifier:
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
@ -1008,6 +1013,10 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
})
DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
TRY_TO(TraverseType(T->getDeducedType()));
})
DEF_TRAVERSE_TYPE(RecordType, {})
DEF_TRAVERSE_TYPE(EnumType, {})
@ -1232,6 +1241,11 @@ DEF_TRAVERSE_TYPELOC(AutoType, {
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
})
DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
})
DEF_TRAVERSE_TYPELOC(RecordType, {})
DEF_TRAVERSE_TYPELOC(EnumType, {})
DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
@ -1932,6 +1946,13 @@ DEF_TRAVERSE_DECL(FunctionDecl, {
ReturnValue = TraverseFunctionHelper(D);
})
DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, {
// We skip decls_begin/decls_end, which are already covered by
// TraverseFunctionHelper().
ShouldVisitChildren = false;
ReturnValue = TraverseFunctionHelper(D);
})
DEF_TRAVERSE_DECL(CXXMethodDecl, {
// We skip decls_begin/decls_end, which are already covered by
// TraverseFunctionHelper().
@ -2495,6 +2516,12 @@ DEF_TRAVERSE_STMT(CoawaitExpr, {
ShouldVisitChildren = false;
}
})
DEF_TRAVERSE_STMT(DependentCoawaitExpr, {
if (!getDerived().shouldVisitImplicitCode()) {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
ShouldVisitChildren = false;
}
})
DEF_TRAVERSE_STMT(CoyieldExpr, {
if (!getDerived().shouldVisitImplicitCode()) {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
@ -2711,6 +2738,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getCondition()));
return true;
}
@ -2724,6 +2752,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getNumThreads()));
return true;
}
@ -2993,6 +3022,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
OMPNumTeamsClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getNumTeams()));
return true;
}
@ -3000,6 +3030,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
OMPThreadLimitClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getThreadLimit()));
return true;
}

View File

@ -39,6 +39,7 @@ namespace clang {
class Expr;
class IdentifierInfo;
class LabelDecl;
class ODRHash;
class ParmVarDecl;
class PrinterHelper;
struct PrintingPolicy;
@ -126,13 +127,13 @@ class alignas(void *) Stmt {
unsigned : NumStmtBits;
unsigned ValueKind : 2;
unsigned ObjectKind : 2;
unsigned ObjectKind : 3;
unsigned TypeDependent : 1;
unsigned ValueDependent : 1;
unsigned InstantiationDependent : 1;
unsigned ContainsUnexpandedParameterPack : 1;
};
enum { NumExprBits = 16 };
enum { NumExprBits = 17 };
class CharacterLiteralBitfields {
friend class CharacterLiteral;
@ -252,6 +253,14 @@ class alignas(void *) Stmt {
unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
};
class CoawaitExprBitfields {
friend class CoawaitExpr;
unsigned : NumExprBits;
unsigned IsImplicit : 1;
};
union {
StmtBitfields StmtBits;
CompoundStmtBitfields CompoundStmtBits;
@ -268,6 +277,7 @@ class alignas(void *) Stmt {
ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
InitListExprBitfields InitListExprBits;
TypeTraitExprBitfields TypeTraitExprBits;
CoawaitExprBitfields CoawaitBits;
};
friend class ASTStmtReader;
@ -340,6 +350,8 @@ class alignas(void *) Stmt {
public:
Stmt(StmtClass SC) {
static_assert(sizeof(*this) == sizeof(void *),
"changing bitfields changed sizeof(Stmt)");
static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
StmtBits.sClass = SC;
@ -436,6 +448,15 @@ class alignas(void *) Stmt {
/// written in the source.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
bool Canonical) const;
/// \brief Calculate a unique representation for a statement that is
/// stable across compiler invocations.
///
/// \param ID profile information will be stored in ID.
///
/// \param Hash an ODRHash object which will be called where pointers would
/// have been used in the Profile function.
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
};
/// DeclStmt - Adaptor class for mixing declarations with statements and

View File

@ -296,7 +296,9 @@ class MSDependentExistsStmt : public Stmt {
/// \brief Represents the body of a coroutine. This wraps the normal function
/// body and holds the additional semantic context required to set up and tear
/// down the coroutine frame.
class CoroutineBodyStmt : public Stmt {
class CoroutineBodyStmt final
: public Stmt,
private llvm::TrailingObjects<CoroutineBodyStmt, Stmt *> {
enum SubStmt {
Body, ///< The body of the coroutine.
Promise, ///< The promise statement.
@ -307,65 +309,100 @@ class CoroutineBodyStmt : public Stmt {
Allocate, ///< Coroutine frame memory allocation.
Deallocate, ///< Coroutine frame memory deallocation.
ReturnValue, ///< Return value for thunk function.
ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
FirstParamMove ///< First offset for move construction of parameter copies.
};
Stmt *SubStmts[SubStmt::FirstParamMove];
unsigned NumParams;
friend class ASTStmtReader;
friend TrailingObjects;
Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
public:
CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
Expr *Allocate, Stmt *Deallocate,
Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
: Stmt(CoroutineBodyStmtClass) {
SubStmts[CoroutineBodyStmt::Body] = Body;
SubStmts[CoroutineBodyStmt::Promise] = Promise;
SubStmts[CoroutineBodyStmt::InitSuspend] = InitSuspend;
SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
SubStmts[CoroutineBodyStmt::OnException] = OnException;
SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
SubStmts[CoroutineBodyStmt::Allocate] = Allocate;
SubStmts[CoroutineBodyStmt::Deallocate] = Deallocate;
SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
// FIXME: Tail-allocate space for parameter move expressions and store them.
assert(ParamMoves.empty() && "not implemented yet");
struct CtorArgs {
Stmt *Body = nullptr;
Stmt *Promise = nullptr;
Expr *InitialSuspend = nullptr;
Expr *FinalSuspend = nullptr;
Stmt *OnException = nullptr;
Stmt *OnFallthrough = nullptr;
Expr *Allocate = nullptr;
Expr *Deallocate = nullptr;
Stmt *ReturnValue = nullptr;
Stmt *ReturnStmtOnAllocFailure = nullptr;
ArrayRef<Stmt *> ParamMoves;
};
private:
CoroutineBodyStmt(CtorArgs const& Args);
public:
static CoroutineBodyStmt *Create(const ASTContext &C, CtorArgs const &Args);
bool hasDependentPromiseType() const {
return getPromiseDecl()->getType()->isDependentType();
}
/// \brief Retrieve the body of the coroutine as written. This will be either
/// a CompoundStmt or a TryStmt.
Stmt *getBody() const {
return SubStmts[SubStmt::Body];
return getStoredStmts()[SubStmt::Body];
}
Stmt *getPromiseDeclStmt() const { return SubStmts[SubStmt::Promise]; }
Stmt *getPromiseDeclStmt() const {
return getStoredStmts()[SubStmt::Promise];
}
VarDecl *getPromiseDecl() const {
return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
}
Stmt *getInitSuspendStmt() const { return SubStmts[SubStmt::InitSuspend]; }
Stmt *getFinalSuspendStmt() const { return SubStmts[SubStmt::FinalSuspend]; }
Stmt *getExceptionHandler() const { return SubStmts[SubStmt::OnException]; }
Stmt *getFallthroughHandler() const {
return SubStmts[SubStmt::OnFallthrough];
Stmt *getInitSuspendStmt() const {
return getStoredStmts()[SubStmt::InitSuspend];
}
Stmt *getFinalSuspendStmt() const {
return getStoredStmts()[SubStmt::FinalSuspend];
}
Expr *getAllocate() const { return cast<Expr>(SubStmts[SubStmt::Allocate]); }
Stmt *getDeallocate() const { return SubStmts[SubStmt::Deallocate]; }
Stmt *getExceptionHandler() const {
return getStoredStmts()[SubStmt::OnException];
}
Stmt *getFallthroughHandler() const {
return getStoredStmts()[SubStmt::OnFallthrough];
}
Expr *getAllocate() const {
return cast_or_null<Expr>(getStoredStmts()[SubStmt::Allocate]);
}
Expr *getDeallocate() const {
return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
}
Expr *getReturnValueInit() const {
return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
return cast_or_null<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
}
Stmt *getReturnStmtOnAllocFailure() const {
return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
}
ArrayRef<Stmt const *> getParamMoves() const {
return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
}
SourceLocation getLocStart() const LLVM_READONLY {
return getBody()->getLocStart();
return getBody() ? getBody()->getLocStart()
: getPromiseDecl()->getLocStart();
}
SourceLocation getLocEnd() const LLVM_READONLY {
return getBody()->getLocEnd();
return getBody() ? getBody()->getLocEnd() : getPromiseDecl()->getLocEnd();
}
child_range children() {
return child_range(SubStmts, SubStmts + SubStmt::FirstParamMove);
return child_range(getStoredStmts(),
getStoredStmts() + SubStmt::FirstParamMove + NumParams);
}
static bool classof(const Stmt *T) {
@ -390,10 +427,14 @@ class CoreturnStmt : public Stmt {
enum SubStmt { Operand, PromiseCall, Count };
Stmt *SubStmts[SubStmt::Count];
bool IsImplicit : 1;
friend class ASTStmtReader;
public:
CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall)
: Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc) {
CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall,
bool IsImplicit = false)
: Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc),
IsImplicit(IsImplicit) {
SubStmts[SubStmt::Operand] = Operand;
SubStmts[SubStmt::PromiseCall] = PromiseCall;
}
@ -411,6 +452,9 @@ class CoreturnStmt : public Stmt {
return static_cast<Expr*>(SubStmts[PromiseCall]);
}
bool isImplicit() const { return IsImplicit; }
void setIsImplicit(bool value = true) { IsImplicit = value; }
SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
return getOperand() ? getOperand()->getLocEnd() : getLocStart();

View File

@ -118,6 +118,8 @@ class StmtIteratorImpl : public StmtIteratorBase,
REFERENCE operator->() const { return operator*(); }
};
struct ConstStmtIterator;
struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
@ -128,6 +130,13 @@ struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
StmtIterator(const VariableArrayType *t)
: StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
private:
StmtIterator(const StmtIteratorBase &RHS)
: StmtIteratorImpl<StmtIterator, Stmt *&>(RHS) {}
inline friend StmtIterator
cast_away_const(const ConstStmtIterator &RHS);
};
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
@ -137,8 +146,15 @@ struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
ConstStmtIterator(const StmtIterator& RHS) :
StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
ConstStmtIterator(Stmt * const *S)
: StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
const_cast<Stmt **>(S)) {}
};
inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
return RHS;
}
} // end namespace clang
#endif

View File

@ -198,6 +198,26 @@ class OMPExecutableDirective : public Stmt {
return const_cast<Stmt *>(*child_begin());
}
/// \brief Returns the captured statement associated with the
/// component region within the (combined) directive.
//
// \param RegionKind Component region kind.
CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
assert(std::any_of(
CaptureRegions.begin(), CaptureRegions.end(),
[=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
"RegionKind not found in OpenMP CaptureRegions.");
auto *CS = cast<CapturedStmt>(getAssociatedStmt());
for (auto ThisCaptureRegion : CaptureRegions) {
if (ThisCaptureRegion == RegionKind)
return CS;
CS = cast<CapturedStmt>(CS->getCapturedStmt());
}
llvm_unreachable("Incorrect RegionKind specified for directive.");
}
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
static bool classof(const Stmt *S) {
@ -304,6 +324,11 @@ class OMPLoopDirective : public OMPExecutableDirective {
/// allocated: loop counters, their updates and final values.
/// PrevLowerBound and PrevUpperBound are used to communicate blocking
/// information in composite constructs which require loop blocking
/// DistInc is used to generate the increment expression for the distribute
/// loop when combined with a further nested loop
/// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
/// for loop when combined with a previous distribute loop in the same pragma
/// (e.g. 'distribute parallel for')
///
enum {
AssociatedStmtOffset = 0,
@ -319,7 +344,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
// specify the offset to the end (and start of the following counters/
// updates/finals arrays).
DefaultEnd = 9,
// The following 7 exprs are used by worksharing loops only.
// The following 12 exprs are used by worksharing and distribute loops only.
IsLastIterVariableOffset = 9,
LowerBoundVariableOffset = 10,
UpperBoundVariableOffset = 11,
@ -330,9 +355,11 @@ class OMPLoopDirective : public OMPExecutableDirective {
NumIterationsOffset = 16,
PrevLowerBoundVariableOffset = 17,
PrevUpperBoundVariableOffset = 18,
DistIncOffset = 19,
PrevEnsureUpperBoundOffset = 20,
// Offset to the end (and start of the following counters/updates/finals
// arrays) for worksharing loop directives.
WorksharingEnd = 19,
WorksharingEnd = 21,
};
/// \brief Get the counters storage.
@ -501,6 +528,20 @@ class OMPLoopDirective : public OMPExecutableDirective {
"expected worksharing loop directive");
*std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
}
void setDistInc(Expr *DistInc) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
*std::next(child_begin(), DistIncOffset) = DistInc;
}
void setPrevEnsureUpperBound(Expr *PrevEUB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
*std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
}
void setCounters(ArrayRef<Expr *> A);
void setPrivateCounters(ArrayRef<Expr *> A);
void setInits(ArrayRef<Expr *> A);
@ -535,7 +576,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
Expr *UB;
/// \brief Stride - local variable passed to runtime.
Expr *ST;
/// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
/// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations).
Expr *EUB;
/// \brief Update of LowerBound for statically sheduled 'omp for' loops.
Expr *NLB;
@ -547,6 +588,16 @@ class OMPLoopDirective : public OMPExecutableDirective {
/// \brief PreviousUpperBound - local variable passed to runtime in the
/// enclosing schedule or null if that does not apply.
Expr *PrevUB;
/// \brief DistInc - increment expression for distribute loop when found
/// combined with a further loop level (e.g. in 'distribute parallel for')
/// expression IV = IV + ST
Expr *DistInc;
/// \brief PrevEUB - expression similar to EUB but to be used when loop
/// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
/// when ensuring that the UB is either the calculated UB by the runtime or
/// the end of the assigned distribute chunk)
/// expression UB = min (UB, PrevUB)
Expr *PrevEUB;
/// \brief Counters Loop counters.
SmallVector<Expr *, 4> Counters;
/// \brief PrivateCounters Loop counters.
@ -588,6 +639,8 @@ class OMPLoopDirective : public OMPExecutableDirective {
NumIterations = nullptr;
PrevLB = nullptr;
PrevUB = nullptr;
DistInc = nullptr;
PrevEUB = nullptr;
Counters.resize(Size);
PrivateCounters.resize(Size);
Inits.resize(Size);
@ -719,6 +772,22 @@ class OMPLoopDirective : public OMPExecutableDirective {
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
*std::next(child_begin(), PrevUpperBoundVariableOffset)));
}
Expr *getDistInc() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
*std::next(child_begin(), DistIncOffset)));
}
Expr *getPrevEnsureUpperBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
*std::next(child_begin(), PrevEnsureUpperBoundOffset)));
}
const Stmt *getBody() const {
// This relies on the loop form is already checked by Sema.
Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);

View File

@ -119,10 +119,7 @@ class TemplateArgument {
public:
/// \brief Construct an empty, invalid template argument.
TemplateArgument() {
TypeOrValue.Kind = Null;
TypeOrValue.V = 0;
}
constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
/// \brief Construct a template type argument.
TemplateArgument(QualType T, bool isNullPtr = false) {
@ -388,8 +385,8 @@ struct TemplateArgumentLocInfo {
};
public:
TemplateArgumentLocInfo();
constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
@ -433,7 +430,7 @@ class TemplateArgumentLoc {
TemplateArgumentLocInfo LocInfo;
public:
TemplateArgumentLoc() {}
constexpr TemplateArgumentLoc() {}
TemplateArgumentLoc(const TemplateArgument &Argument,
TemplateArgumentLocInfo Opaque)
@ -578,6 +575,7 @@ struct ASTTemplateArgumentListInfo final
TemplateArgumentLoc> {
private:
friend TrailingObjects;
friend class ASTNodeImporter;
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);

View File

@ -333,6 +333,20 @@ class Qualifiers {
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
/// Get the address space attribute value to be printed by diagnostics.
unsigned getAddressSpaceAttributePrintValue() const {
auto Addr = getAddressSpace();
// This function is not supposed to be used with language specific
// address spaces. If that happens, the diagnostic message should consider
// printing the QualType instead of the address space value.
assert(Addr == 0 || Addr >= LangAS::Count);
if (Addr)
return Addr - LangAS::Count;
// TODO: The diagnostic messages where Addr may be 0 should be fixed
// since it cannot differentiate the situation where 0 denotes the default
// address space or user specified __attribute__((address_space(0))).
return 0;
}
void setAddressSpace(unsigned space) {
assert(space <= MaxAddressSpace);
Mask = (Mask & ~AddressSpaceMask)
@ -1020,6 +1034,9 @@ class QualType {
return getQualifiers().hasStrongOrWeakObjCLifetime();
}
// true when Type is objc's weak and weak is enabled but ARC isn't.
bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
enum DestructionKind {
DK_none,
DK_cxx_destructor,
@ -1744,7 +1761,6 @@ class Type : public ExtQualsTypeCommonBase {
bool isEventT() const; // OpenCL event_t
bool isClkEventT() const; // OpenCL clk_event_t
bool isQueueT() const; // OpenCL queue_t
bool isNDRangeT() const; // OpenCL ndrange_t
bool isReserveIDT() const; // OpenCL reserve_id_t
bool isPipeType() const; // OpenCL pipe type
@ -1785,7 +1801,8 @@ class Type : public ExtQualsTypeCommonBase {
}
/// \brief Determine whether this type is an undeduced type, meaning that
/// it somehow involves a C++11 'auto' type which has not yet been deduced.
/// it somehow involves a C++11 'auto' type or similar which has not yet been
/// deduced.
bool isUndeducedType() const;
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
@ -1862,10 +1879,22 @@ class Type : public ExtQualsTypeCommonBase {
/// not refer to a CXXRecordDecl, returns NULL.
const CXXRecordDecl *getPointeeCXXRecordDecl() const;
/// Get the DeducedType whose type will be deduced for a variable with
/// an initializer of this type. This looks through declarators like pointer
/// types, but not through decltype or typedefs.
DeducedType *getContainedDeducedType() const;
/// Get the AutoType whose type will be deduced for a variable with
/// an initializer of this type. This looks through declarators like pointer
/// types, but not through decltype or typedefs.
AutoType *getContainedAutoType() const;
AutoType *getContainedAutoType() const {
return dyn_cast_or_null<AutoType>(getContainedDeducedType());
}
/// Determine whether this type was written with a leading 'auto'
/// corresponding to a trailing return type (possibly for a nested
/// function type within a pointer to function type or similar).
bool hasAutoForTrailingReturnType() const;
/// Member-template getAs<specific type>'. Look through sugar for
/// an instance of \<specific type>. This scheme will eventually
@ -1875,6 +1904,13 @@ class Type : public ExtQualsTypeCommonBase {
/// immediately following this class.
template <typename T> const T *getAs() const;
/// Member-template getAsAdjusted<specific type>. Look through specific kinds
/// of sugar (parens, attributes, etc) for an instance of \<specific type>.
/// This is used when you need to walk over sugar nodes that represent some
/// kind of type adjustment from a type that was written as a \<specific type>
/// to another type that is still canonically a \<specific type>.
template <typename T> const T *getAsAdjusted() const;
/// A variant of getAs<> for array types which silently discards
/// qualifiers from the outermost type.
const ArrayType *getAsArrayTypeUnsafe() const;
@ -2057,7 +2093,7 @@ class BuiltinType : public Type {
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
/*InstantiationDependent=*/(K == Dependent),
/*VariablyModified=*/false,
/*Unexpanded paramter pack=*/false) {
/*Unexpanded parameter pack=*/false) {
BuiltinTypeBits.Kind = K;
}
@ -3097,9 +3133,11 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
class ExtParameterInfo {
enum {
ABIMask = 0x0F,
IsConsumed = 0x10
IsConsumed = 0x10,
HasPassObjSize = 0x20,
};
unsigned char Data;
public:
ExtParameterInfo() : Data(0) {}
@ -3128,6 +3166,15 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
return copy;
}
bool hasPassObjectSize() const {
return Data & HasPassObjSize;
}
ExtParameterInfo withHasPassObjectSize() const {
ExtParameterInfo Copy = *this;
Copy.Data |= HasPassObjSize;
return Copy;
}
unsigned char getOpaqueValue() const { return Data; }
static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
ExtParameterInfo result;
@ -4089,25 +4136,60 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
}
};
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
/// \brief Common base class for placeholders for types that get replaced by
/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
/// class template types, and (eventually) constrained type names from the C++
/// Concepts TS.
///
/// These types are usually a placeholder for a deduced type. However, before
/// the initializer is attached, or (usually) if the initializer is
/// type-dependent, there is no deduced type and an auto type is canonical. In
/// type-dependent, there is no deduced type and the type is canonical. In
/// the latter case, it is also a dependent type.
class AutoType : public Type, public llvm::FoldingSetNode {
AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
/*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
if (!DeducedType.isNull()) {
if (DeducedType->isDependentType())
class DeducedType : public Type {
protected:
DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent,
bool IsInstantiationDependent, bool ContainsParameterPack)
: Type(TC,
// FIXME: Retain the sugared deduced type?
DeducedAsType.isNull() ? QualType(this, 0)
: DeducedAsType.getCanonicalType(),
IsDependent, IsInstantiationDependent,
/*VariablyModified=*/false, ContainsParameterPack) {
if (!DeducedAsType.isNull()) {
if (DeducedAsType->isDependentType())
setDependent();
if (DeducedType->isInstantiationDependentType())
if (DeducedAsType->isInstantiationDependentType())
setInstantiationDependent();
if (DeducedType->containsUnexpandedParameterPack())
if (DeducedAsType->containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack();
}
}
public:
bool isSugared() const { return !isCanonicalUnqualified(); }
QualType desugar() const { return getCanonicalTypeInternal(); }
/// \brief Get the type deduced for this placeholder type, or null if it's
/// either not been deduced or was deduced to a dependent type.
QualType getDeducedType() const {
return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
}
bool isDeduced() const {
return !isCanonicalUnqualified() || isDependentType();
}
static bool classof(const Type *T) {
return T->getTypeClass() == Auto ||
T->getTypeClass() == DeducedTemplateSpecialization;
}
};
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
class AutoType : public DeducedType, public llvm::FoldingSetNode {
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
bool IsDeducedAsDependent)
: DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
IsDeducedAsDependent, /*ContainsPack=*/false) {
AutoTypeBits.Keyword = (unsigned)Keyword;
}
@ -4121,18 +4203,6 @@ class AutoType : public Type, public llvm::FoldingSetNode {
return (AutoTypeKeyword)AutoTypeBits.Keyword;
}
bool isSugared() const { return !isCanonicalUnqualified(); }
QualType desugar() const { return getCanonicalTypeInternal(); }
/// \brief Get the type deduced for this auto type, or null if it's either
/// not been deduced or was deduced to a dependent type.
QualType getDeducedType() const {
return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
}
bool isDeduced() const {
return !isCanonicalUnqualified() || isDependentType();
}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getDeducedType(), getKeyword(), isDependentType());
}
@ -4149,6 +4219,43 @@ class AutoType : public Type, public llvm::FoldingSetNode {
}
};
/// \brief Represents a C++17 deduced template specialization type.
class DeducedTemplateSpecializationType : public DeducedType,
public llvm::FoldingSetNode {
/// The name of the template whose arguments will be deduced.
TemplateName Template;
DeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedAsType,
bool IsDeducedAsDependent)
: DeducedType(DeducedTemplateSpecialization, DeducedAsType,
IsDeducedAsDependent || Template.isDependent(),
IsDeducedAsDependent || Template.isInstantiationDependent(),
Template.containsUnexpandedParameterPack()),
Template(Template) {}
friend class ASTContext; // ASTContext creates these
public:
/// Retrieve the name of the template that we are deducing.
TemplateName getTemplateName() const { return Template;}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
}
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
QualType Deduced, bool IsDependent) {
Template.Profile(ID);
ID.AddPointer(Deduced.getAsOpaquePtr());
ID.AddBoolean(IsDependent);
}
static bool classof(const Type *T) {
return T->getTypeClass() == DeducedTemplateSpecialization;
}
};
/// \brief Represents a type template specialization; the template
/// must be a class template, a type alias template, or a template
/// template parameter. A template which cannot be resolved to one of
@ -4345,6 +4452,9 @@ class InjectedClassNameType : public Type {
const TemplateSpecializationType *getInjectedTST() const {
return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
}
TemplateName getTemplateName() const {
return getInjectedTST()->getTemplateName();
}
CXXRecordDecl *getDecl() const;
@ -5718,10 +5828,6 @@ inline bool Type::isQueueT() const {
return isSpecificBuiltinType(BuiltinType::OCLQueue);
}
inline bool Type::isNDRangeT() const {
return isSpecificBuiltinType(BuiltinType::OCLNDRange);
}
inline bool Type::isReserveIDT() const {
return isSpecificBuiltinType(BuiltinType::OCLReserveID);
}
@ -5739,7 +5845,7 @@ inline bool Type::isPipeType() const {
inline bool Type::isOpenCLSpecificType() const {
return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType();
isQueueT() || isReserveIDT() || isPipeType();
}
inline bool Type::isTemplateTypeParmType() const {
@ -5849,8 +5955,8 @@ inline bool Type::isBooleanType() const {
}
inline bool Type::isUndeducedType() const {
const AutoType *AT = getContainedAutoType();
return AT && !AT->isDeduced();
auto *DT = getContainedDeducedType();
return DT && !DT->isDeduced();
}
/// \brief Determines whether this is a type for which one can define
@ -5932,6 +6038,38 @@ template <typename T> const T *Type::getAs() const {
return cast<T>(getUnqualifiedDesugaredType());
}
template <typename T> const T *Type::getAsAdjusted() const {
static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
// If this is directly a T type, return it.
if (const T *Ty = dyn_cast<T>(this))
return Ty;
// If the canonical form of this type isn't the right kind, reject it.
if (!isa<T>(CanonicalType))
return nullptr;
// Strip off type adjustments that do not modify the underlying nature of the
// type.
const Type *Ty = this;
while (Ty) {
if (const auto *A = dyn_cast<AttributedType>(Ty))
Ty = A->getModifiedType().getTypePtr();
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
Ty = E->desugar().getTypePtr();
else if (const auto *P = dyn_cast<ParenType>(Ty))
Ty = P->desugar().getTypePtr();
else if (const auto *A = dyn_cast<AdjustedType>(Ty))
Ty = A->desugar().getTypePtr();
else
break;
}
// Just because the canonical type is correct does not mean we can use cast<>,
// since we may not have stripped off all the sugar down to the base type.
return dyn_cast<T>(Ty);
}
inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
// If this is directly an array type, return it.
if (const ArrayType *arr = dyn_cast<ArrayType>(this))

View File

@ -70,6 +70,13 @@ class TypeLoc {
return t;
}
/// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
/// this TypeLock is not of the desired type. It will consider type
/// adjustments from a type that wad written as a T to another type that is
/// still canonically a T (ignores parens, attributes, elaborated types, etc).
template <typename T>
T getAsAdjusted() const;
/// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
/// except it also defines a Qualified enum that corresponds to the
/// QualifiedLoc class.
@ -1827,9 +1834,25 @@ class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
}
};
class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
AutoTypeLoc,
AutoType> {
class DeducedTypeLoc
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
DeducedType> {};
class AutoTypeLoc
: public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
};
class DeducedTemplateSpecializationTypeLoc
: public InheritingConcreteTypeLoc<DeducedTypeLoc,
DeducedTemplateSpecializationTypeLoc,
DeducedTemplateSpecializationType> {
public:
SourceLocation getTemplateNameLoc() const {
return getNameLoc();
}
void setTemplateNameLoc(SourceLocation Loc) {
setNameLoc(Loc);
}
};
struct ElaboratedLocInfo {
@ -2172,6 +2195,24 @@ class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
};
template <typename T>
inline T TypeLoc::getAsAdjusted() const {
TypeLoc Cur = *this;
while (!T::isKind(Cur)) {
if (auto PTL = Cur.getAs<ParenTypeLoc>())
Cur = PTL.getInnerLoc();
else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
Cur = ATL.getModifiedLoc();
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
Cur = ETL.getNamedTypeLoc();
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
Cur = ATL.getOriginalLoc();
else
break;
}
return Cur.getAs<T>();
}
}
#endif

View File

@ -96,7 +96,9 @@ DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
TYPE(Auto, Type)
ABSTRACT_TYPE(Deduced, Type)
TYPE(Auto, DeducedType)
TYPE(DeducedTemplateSpecialization, DeducedType)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)

View File

@ -26,7 +26,7 @@
namespace clang {
/// \brief Function object that provides a total ordering on QualType values.
struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
struct QualTypeOrdering {
bool operator()(QualType T1, QualType T2) const {
return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
}

View File

@ -180,6 +180,16 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
/// matches "using Y = int", but not "typedef int X"
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
/// \brief Matches type alias template declarations.
///
/// typeAliasTemplateDecl() matches
/// \code
/// template <typename T>
/// using Y = X<T>;
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
typeAliasTemplateDecl;
/// \brief Matches AST nodes that were expanded within the main-file.
///
/// Example matches X but not Y
@ -1118,6 +1128,69 @@ const internal::VariadicDynCastAllOfMatcher<
Decl,
ObjCInterfaceDecl> objcInterfaceDecl;
/// \brief Matches Objective-C protocol declarations.
///
/// Example matches FooDelegate
/// \code
/// @protocol FooDelegate
/// @end
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
ObjCProtocolDecl> objcProtocolDecl;
/// \brief Matches Objective-C category declarations.
///
/// Example matches Foo (Additions)
/// \code
/// @interface Foo (Additions)
/// @end
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
ObjCCategoryDecl> objcCategoryDecl;
/// \brief Matches Objective-C method declarations.
///
/// Example matches both declaration and definition of -[Foo method]
/// \code
/// @interface Foo
/// - (void)method;
/// @end
///
/// @implementation Foo
/// - (void)method {}
/// @end
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
ObjCMethodDecl> objcMethodDecl;
/// \brief Matches Objective-C instance variable declarations.
///
/// Example matches _enabled
/// \code
/// @implementation Foo {
/// BOOL _enabled;
/// }
/// @end
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
ObjCIvarDecl> objcIvarDecl;
/// \brief Matches Objective-C property declarations.
///
/// Example matches enabled
/// \code
/// @interface Foo
/// @property BOOL enabled;
/// @end
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
ObjCPropertyDecl> objcPropertyDecl;
/// \brief Matches expressions that introduce cleanups to be run at the end
/// of the sub-expression's evaluation.
///
@ -2522,7 +2595,7 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
/// \brief Matches on the receiver of an ObjectiveC Message expression.
///
/// Example
/// matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
/// matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
/// matches the [webView ...] message invocation.
/// \code
/// NSString *webViewJavaScript = ...
@ -5507,7 +5580,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant) {
integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
}
/// \brief Matches declaration of the function the statemenet belongs to
/// \brief Matches declaration of the function the statement belongs to
///
/// Given:
/// \code

View File

@ -56,7 +56,7 @@ class ArgKind {
/// \param To the requested destination type.
///
/// \param Specificity value corresponding to the "specificity" of the
/// convertion.
/// conversion.
bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
bool operator<(const ArgKind &Other) const {
@ -182,7 +182,7 @@ class VariantMatcher {
/// \param Kind the requested destination type.
///
/// \param Specificity value corresponding to the "specificity" of the
/// convertion.
/// conversion.
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
unsigned *Specificity) const {
if (Value)
@ -281,7 +281,7 @@ class VariantValue {
/// \param Kind the requested destination type.
///
/// \param Specificity value corresponding to the "specificity" of the
/// convertion.
/// conversion.
bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
/// \brief Determines if the contained value can be converted to any kind
@ -290,7 +290,7 @@ class VariantValue {
/// \param Kinds the requested destination types.
///
/// \param Specificity value corresponding to the "specificity" of the
/// convertion. It is the maximum specificity of all the possible
/// conversion. It is the maximum specificity of all the possible
/// conversions.
bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;

View File

@ -98,7 +98,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
bool VisitFunctionDecl(FunctionDecl *FD) {
// We skip function template definitions, as their semantics is
// only determined when they are instantiated.
if (includeInGraph(FD)) {
if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
// Add all blocks declared inside this function to the graph.
addNodesForBlocks(FD);
// If this function has external linkage, anything could call it.

View File

@ -16,9 +16,7 @@
#define LLVM_CLANG_AST_CLONEDETECTION_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
namespace clang {
@ -29,7 +27,7 @@ class VarDecl;
class ASTContext;
class CompoundStmt;
/// \brief Identifies a list of statements.
/// Identifies a list of statements.
///
/// Can either identify a single arbitrary Stmt object, a continuous sequence of
/// child statements inside a CompoundStmt or no statements at all.
@ -39,8 +37,8 @@ class StmtSequence {
/// Stmt, then S is a pointer to this Stmt.
const Stmt *S;
/// The related ASTContext for S.
ASTContext *Context;
/// The declaration that contains the statements.
const Decl *D;
/// If EndIndex is non-zero, then S is a CompoundStmt and this StmtSequence
/// instance is representing the CompoundStmt children inside the array
@ -49,7 +47,7 @@ class StmtSequence {
unsigned EndIndex;
public:
/// \brief Constructs a StmtSequence holding multiple statements.
/// Constructs a StmtSequence holding multiple statements.
///
/// The resulting StmtSequence identifies a continuous sequence of statements
/// in the body of the given CompoundStmt. Which statements of the body should
@ -57,20 +55,20 @@ class StmtSequence {
/// that describe a non-empty sub-array in the body of the given CompoundStmt.
///
/// \param Stmt A CompoundStmt that contains all statements in its body.
/// \param Context The ASTContext for the given CompoundStmt.
/// \param D The Decl containing this Stmt.
/// \param StartIndex The inclusive start index in the children array of
/// \p Stmt
/// \param EndIndex The exclusive end index in the children array of \p Stmt.
StmtSequence(const CompoundStmt *Stmt, ASTContext &Context,
unsigned StartIndex, unsigned EndIndex);
StmtSequence(const CompoundStmt *Stmt, const Decl *D, unsigned StartIndex,
unsigned EndIndex);
/// \brief Constructs a StmtSequence holding a single statement.
/// Constructs a StmtSequence holding a single statement.
///
/// \param Stmt An arbitrary Stmt.
/// \param Context The ASTContext for the given Stmt.
StmtSequence(const Stmt *Stmt, ASTContext &Context);
/// \param D The Decl containing this Stmt.
StmtSequence(const Stmt *Stmt, const Decl *D);
/// \brief Constructs an empty StmtSequence.
/// Constructs an empty StmtSequence.
StmtSequence();
typedef const Stmt *const *iterator;
@ -110,9 +108,12 @@ class StmtSequence {
bool empty() const { return size() == 0; }
/// Returns the related ASTContext for the stored Stmts.
ASTContext &getASTContext() const {
assert(Context);
return *Context;
ASTContext &getASTContext() const;
/// Returns the declaration that contains the stored Stmts.
const Decl *getContainingDecl() const {
assert(D);
return D;
}
/// Returns true if this objects holds a list of statements.
@ -150,106 +151,215 @@ class StmtSequence {
bool contains(const StmtSequence &Other) const;
};
/// \brief Searches for clones in source code.
/// Searches for similar subtrees in the AST.
///
/// First, this class needs a translation unit which is passed via
/// \p analyzeTranslationUnit . It will then generate and store search data
/// for all statements inside the given translation unit.
/// Afterwards the generated data can be used to find code clones by calling
/// \p findClones .
/// First, this class needs several declarations with statement bodies which
/// can be passed via analyzeCodeBody. Afterwards all statements can be
/// searched for clones by calling findClones with a given list of constraints
/// that should specify the wanted properties of the clones.
///
/// The result of findClones can be further constrained with the constrainClones
/// method.
///
/// This class only searches for clones in exectuable source code
/// (e.g. function bodies). Other clones (e.g. cloned comments or declarations)
/// are not supported.
class CloneDetector {
public:
typedef unsigned DataPiece;
/// A collection of StmtSequences that share an arbitrary property.
typedef llvm::SmallVector<StmtSequence, 8> CloneGroup;
/// Holds the data about a StmtSequence that is needed during the search for
/// code clones.
struct CloneSignature {
/// \brief The hash code of the StmtSequence.
///
/// The initial clone groups that are formed during the search for clones
/// consist only of Sequences that share the same hash code. This makes this
/// value the central part of this heuristic that is needed to find clones
/// in a performant way. For this to work, the type of this variable
/// always needs to be small and fast to compare.
///
/// Also, StmtSequences that are clones of each others have to share
/// the same hash code. StmtSequences that are not clones of each other
/// shouldn't share the same hash code, but if they do, it will only
/// degrade the performance of the hash search but doesn't influence
/// the correctness of the result.
size_t Hash;
/// \brief The complexity of the StmtSequence.
///
/// This value gives an approximation on how many direct or indirect child
/// statements are contained in the related StmtSequence. In general, the
/// greater this value, the greater the amount of statements. However, this
/// is only an approximation and the actual amount of statements can be
/// higher or lower than this value. Statements that are generated by the
/// compiler (e.g. macro expansions) for example barely influence the
/// complexity value.
///
/// The main purpose of this value is to filter clones that are too small
/// and therefore probably not interesting enough for the user.
unsigned Complexity;
/// \brief Creates an empty CloneSignature without any data.
CloneSignature() : Complexity(1) {}
CloneSignature(llvm::hash_code Hash, unsigned Complexity)
: Hash(Hash), Complexity(Complexity) {}
};
/// Holds group of StmtSequences that are clones of each other and the
/// complexity value (see CloneSignature::Complexity) that all stored
/// StmtSequences have in common.
struct CloneGroup {
std::vector<StmtSequence> Sequences;
CloneSignature Signature;
CloneGroup() {}
CloneGroup(const StmtSequence &Seq, CloneSignature Signature)
: Signature(Signature) {
Sequences.push_back(Seq);
}
/// \brief Returns false if and only if this group should be skipped when
/// searching for clones.
bool isValid() const {
// A clone group with only one member makes no sense, so we skip them.
return Sequences.size() > 1;
}
};
/// \brief Generates and stores search data for all statements in the body of
/// the given Decl.
/// Generates and stores search data for all statements in the body of
/// the given Decl.
void analyzeCodeBody(const Decl *D);
/// \brief Stores the CloneSignature to allow future querying.
void add(const StmtSequence &S, const CloneSignature &Signature);
/// \brief Searches the provided statements for clones.
/// Constrains the given list of clone groups with the given constraint.
///
/// \param Result Output parameter that is filled with a list of found
/// clone groups. Each group contains multiple StmtSequences
/// that were identified to be clones of each other.
/// \param MinGroupComplexity Only return clones which have at least this
/// complexity value.
/// \param CheckPatterns Returns only clone groups in which the referenced
/// variables follow the same pattern.
void findClones(std::vector<CloneGroup> &Result, unsigned MinGroupComplexity,
bool CheckPatterns = true);
/// The constraint is expected to have a method with the signature
/// `void constrain(std::vector<CloneDetector::CloneGroup> &Sequences)`
/// as this is the interface that the CloneDetector uses for applying the
/// constraint. The constraint is supposed to directly modify the passed list
/// so that all clones in the list fulfill the specific property this
/// constraint ensures.
template <typename T>
static void constrainClones(std::vector<CloneGroup> &CloneGroups, T C) {
C.constrain(CloneGroups);
}
/// \brief Describes two clones that reference their variables in a different
/// pattern which could indicate a programming error.
/// Constrains the given list of clone groups with the given list of
/// constraints.
///
/// The constraints are applied in sequence in the order in which they are
/// passed to this function.
template <typename T1, typename... Ts>
static void constrainClones(std::vector<CloneGroup> &CloneGroups, T1 C,
Ts... ConstraintList) {
constrainClones(CloneGroups, C);
constrainClones(CloneGroups, ConstraintList...);
}
/// Searches for clones in all previously passed statements.
/// \param Result Output parameter to which all created clone groups are
/// added.
/// \param ConstraintList The constraints that should be applied to the
// result.
template <typename... Ts>
void findClones(std::vector<CloneGroup> &Result, Ts... ConstraintList) {
// The initial assumption is that there is only one clone group and every
// statement is a clone of the others. This clone group will then be
// split up with the help of the constraints.
CloneGroup AllClones;
AllClones.reserve(Sequences.size());
for (const auto &C : Sequences) {
AllClones.push_back(C);
}
Result.push_back(AllClones);
constrainClones(Result, ConstraintList...);
}
private:
CloneGroup Sequences;
};
/// This class is a utility class that contains utility functions for building
/// custom constraints.
class CloneConstraint {
public:
/// Removes all groups by using a filter function.
/// \param CloneGroups The list of CloneGroups that is supposed to be
/// filtered.
/// \param Filter The filter function that should return true for all groups
/// that should be removed from the list.
static void
filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups,
std::function<bool(const CloneDetector::CloneGroup &)> Filter) {
CloneGroups.erase(
std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
CloneGroups.end());
}
/// Splits the given CloneGroups until the given Compare function returns true
/// for all clones in a single group.
/// \param CloneGroups A list of CloneGroups that should be modified.
/// \param Compare The comparison function that all clones are supposed to
/// pass. Should return true if and only if two clones belong
/// to the same CloneGroup.
static void splitCloneGroups(
std::vector<CloneDetector::CloneGroup> &CloneGroups,
std::function<bool(const StmtSequence &, const StmtSequence &)> Compare);
};
/// Searches all children of the given clones for type II clones (i.e. they are
/// identical in every aspect beside the used variable names).
class RecursiveCloneTypeIIConstraint {
/// Generates and saves a hash code for the given Stmt.
/// \param S The given Stmt.
/// \param D The Decl containing S.
/// \param StmtsByHash Output parameter that will contain the hash codes for
/// each StmtSequence in the given Stmt.
/// \return The hash code of the given Stmt.
///
/// If the given Stmt is a CompoundStmt, this method will also generate
/// hashes for all possible StmtSequences in the children of this Stmt.
size_t saveHash(const Stmt *S, const Decl *D,
std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash);
public:
void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
};
/// Ensures that every clone has at least the given complexity.
///
/// Complexity is here defined as the total amount of children of a statement.
/// This constraint assumes the first statement in the group is representative
/// for all other statements in the group in terms of complexity.
class MinComplexityConstraint {
unsigned MinComplexity;
public:
MinComplexityConstraint(unsigned MinComplexity)
: MinComplexity(MinComplexity) {}
size_t calculateStmtComplexity(const StmtSequence &Seq,
const std::string &ParentMacroStack = "");
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
CloneConstraint::filterGroups(
CloneGroups, [this](const CloneDetector::CloneGroup &A) {
if (!A.empty())
return calculateStmtComplexity(A.front()) < MinComplexity;
else
return false;
});
}
};
/// Ensures that all clone groups contain at least the given amount of clones.
class MinGroupSizeConstraint {
unsigned MinGroupSize;
public:
MinGroupSizeConstraint(unsigned MinGroupSize = 2)
: MinGroupSize(MinGroupSize) {}
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
CloneConstraint::filterGroups(CloneGroups,
[this](const CloneDetector::CloneGroup &A) {
return A.size() < MinGroupSize;
});
}
};
/// Ensures that no clone group fully contains another clone group.
struct OnlyLargestCloneConstraint {
void constrain(std::vector<CloneDetector::CloneGroup> &Result);
};
/// Analyzes the pattern of the referenced variables in a statement.
class VariablePattern {
/// Describes an occurence of a variable reference in a statement.
struct VariableOccurence {
/// The index of the associated VarDecl in the Variables vector.
size_t KindID;
/// The statement in the code where the variable was referenced.
const Stmt *Mention;
VariableOccurence(size_t KindID, const Stmt *Mention)
: KindID(KindID), Mention(Mention) {}
};
/// All occurences of referenced variables in the order of appearance.
std::vector<VariableOccurence> Occurences;
/// List of referenced variables in the order of appearance.
/// Every item in this list is unique.
std::vector<const VarDecl *> Variables;
/// Adds a new variable referenced to this pattern.
/// \param VarDecl The declaration of the variable that is referenced.
/// \param Mention The SourceRange where this variable is referenced.
void addVariableOccurence(const VarDecl *VarDecl, const Stmt *Mention);
/// Adds each referenced variable from the given statement.
void addVariables(const Stmt *S);
public:
/// Creates an VariablePattern object with information about the given
/// StmtSequence.
VariablePattern(const StmtSequence &Sequence) {
for (const Stmt *S : Sequence)
addVariables(S);
}
/// Describes two clones that reference their variables in a different pattern
/// which could indicate a programming error.
struct SuspiciousClonePair {
/// \brief Utility class holding the relevant information about a single
/// clone in this pair.
/// Utility class holding the relevant information about a single
/// clone in this pair.
struct SuspiciousCloneInfo {
/// The variable which referencing in this clone was against the pattern.
const VarDecl *Variable;
@ -270,17 +380,37 @@ class CloneDetector {
SuspiciousCloneInfo SecondCloneInfo;
};
/// \brief Searches the provided statements for pairs of clones that don't
/// follow the same pattern when referencing variables.
/// \param Result Output parameter that will contain the clone pairs.
/// \param MinGroupComplexity Only clone pairs in which the clones have at
/// least this complexity value.
void findSuspiciousClones(std::vector<SuspiciousClonePair> &Result,
unsigned MinGroupComplexity);
/// Counts the differences between this pattern and the given one.
/// \param Other The given VariablePattern to compare with.
/// \param FirstMismatch Output parameter that will be filled with information
/// about the first difference between the two patterns. This parameter
/// can be a nullptr, in which case it will be ignored.
/// \return Returns the number of differences between the pattern this object
/// is following and the given VariablePattern.
///
/// For example, the following statements all have the same pattern and this
/// function would return zero:
///
/// if (a < b) return a; return b;
/// if (x < y) return x; return y;
/// if (u2 < u1) return u2; return u1;
///
/// But the following statement has a different pattern (note the changed
/// variables in the return statements) and would have two differences when
/// compared with one of the statements above.
///
/// if (a < b) return b; return a;
///
/// This function should only be called if the related statements of the given
/// pattern and the statements of this objects are clones of each other.
unsigned countPatternDifferences(
const VariablePattern &Other,
VariablePattern::SuspiciousClonePair *FirstMismatch = nullptr);
};
private:
/// Stores all encountered StmtSequences alongside their CloneSignature.
std::vector<std::pair<CloneSignature, StmtSequence>> Sequences;
/// Ensures that all clones reference variables in the same pattern.
struct MatchingVariablePatternConstraint {
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups);
};
} // end namespace clang

View File

@ -20,24 +20,32 @@ namespace clang {
namespace LangAS {
/// \brief Defines the set of possible language-specific address spaces.
/// \brief Defines the address space values used by the address space qualifier
/// of QualType.
///
/// This uses a high starting offset so as not to conflict with any address
/// space used by a target.
enum ID {
Offset = 0x7FFF00,
// The default value 0 is the value used in QualType for the the situation
// where there is no address space qualifier. For most languages, this also
// corresponds to the situation where there is no address space qualifier in
// the source code, except for OpenCL, where the address space value 0 in
// QualType represents private address space in OpenCL source code.
Default = 0,
opencl_global = Offset,
// OpenCL specific address spaces.
opencl_global,
opencl_local,
opencl_constant,
opencl_generic,
// CUDA specific address spaces.
cuda_device,
cuda_constant,
cuda_shared,
Last,
Count = Last-Offset
// This denotes the count of language-specific address spaces and also
// the offset added to the target-specific address spaces, which are usually
// specified by address space attributes __attribute__(address_space(n))).
Count
};
/// The type of a lookup table which maps from language-specific address spaces

View File

@ -258,6 +258,7 @@ class TargetArch<list<string> arches> {
list<string> CXXABIs;
}
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
def TargetAVR : TargetArch<["avr"]>;
def TargetMips : TargetArch<["mips", "mipsel"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
def TargetX86 : TargetArch<["x86"]>;
@ -301,6 +302,9 @@ class Attr {
// Set to true if this attribute can be duplicated on a subject when merging
// attributes. By default, attributes are not merged.
bit DuplicatesAllowedWhileMerging = 0;
// Set to true if this attribute meaningful when applied to or inherited
// in a class template definition.
bit MeaningfulToClassTemplateDefinition = 0;
// Lists language options, one of which is required to be true for the
// attribute to be applicable. If empty, no language options are required.
list<LangOpt> LangOpts = [];
@ -340,7 +344,7 @@ class TargetSpecificAttr<TargetArch target> {
// should contain a shared value between the attributes.
//
// Target-specific attributes which use this feature should ensure that the
// spellings match exactly betweeen the attributes, and if the arguments or
// spellings match exactly between the attributes, and if the arguments or
// subjects differ, should specify HasCustomParsing = 1 and implement their
// own parsing and semantic handling requirements as-needed.
string ParseKind;
@ -372,6 +376,7 @@ def AbiTag : Attr {
let Args = [VariadicStringArgument<"Tags">];
let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
"ExpectedStructClassVariableFunctionOrInlineNamespace">;
let MeaningfulToClassTemplateDefinition = 1;
let Documentation = [AbiTagsDocs];
}
@ -449,6 +454,15 @@ def XRayInstrument : InheritableAttr {
let Documentation = [XRayDocs];
}
def XRayLogArgs : InheritableAttr {
let Spellings = [GNU<"xray_log_args">, CXX11<"clang", "xray_log_args">];
let Subjects = SubjectList<
[CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
>;
let Args = [UnsignedArgument<"ArgumentCount">];
let Documentation = [XRayDocs];
}
def TLSModel : InheritableAttr {
let Spellings = [GCC<"tls_model">];
let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
@ -480,6 +494,19 @@ def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
let Documentation = [ARMInterruptDocs];
}
def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
let Spellings = [GNU<"interrupt">];
let Subjects = SubjectList<[Function]>;
let ParseKind = "Interrupt";
let Documentation = [AVRInterruptDocs];
}
def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
let Spellings = [GNU<"signal">];
let Subjects = SubjectList<[Function]>;
let Documentation = [AVRSignalDocs];
}
def AsmLabel : InheritableAttr {
let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
let Args = [StringArgument<"Label">];
@ -513,6 +540,17 @@ def Availability : InheritableAttr {
let Documentation = [AvailabilityDocs];
}
def ExternalSourceSymbol : InheritableAttr {
let Spellings = [GNU<"external_source_symbol">,
CXX11<"clang", "external_source_symbol">];
let Args = [StringArgument<"language", 1>,
StringArgument<"definedIn", 1>,
BoolArgument<"generatedDeclaration", 1>];
let HasCustomParsing = 1;
// let Subjects = SubjectList<[Named]>;
let Documentation = [ExternalSourceSymbolDocs];
}
def Blocks : InheritableAttr {
let Spellings = [GNU<"blocks">];
let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
@ -771,6 +809,7 @@ def Deprecated : InheritableAttr {
// An optional string argument that enables us to provide a
// Fix-It.
StringArgument<"Replacement", 1>];
let MeaningfulToClassTemplateDefinition = 1;
let Documentation = [DeprecatedDocs];
}
@ -847,7 +886,15 @@ def FlagEnum : InheritableAttr {
let Spellings = [GNU<"flag_enum">];
let Subjects = SubjectList<[Enum]>;
let Documentation = [FlagEnumDocs];
let LangOpts = [COnly];
}
def EnumExtensibility : InheritableAttr {
let Spellings = [GNU<"enum_extensibility">,
CXX11<"clang", "enum_extensibility">];
let Subjects = SubjectList<[Enum]>;
let Args = [EnumArgument<"Extensibility", "Kind",
["closed", "open"], ["Closed", "Open"]>];
let Documentation = [EnumExtensibilityDocs];
}
def Flatten : InheritableAttr {
@ -1115,7 +1162,7 @@ def NoSplitStack : InheritableAttr {
let Documentation = [NoSplitStackDocs];
}
def NonNull : InheritableAttr {
def NonNull : InheritableParamAttr {
let Spellings = [GCC<"nonnull">];
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
"ExpectedFunctionMethodOrParameter">;
@ -1178,6 +1225,14 @@ def AssumeAligned : InheritableAttr {
let Documentation = [AssumeAlignedDocs];
}
def AllocAlign : InheritableAttr {
let Spellings = [GCC<"alloc_align">];
let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
"ExpectedFunctionWithProtoType">;
let Args = [IntArgument<"ParamIndex">];
let Documentation = [AllocAlignDocs];
}
def NoReturn : InheritableAttr {
let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
// FIXME: Does GCC allow this on the function instead?
@ -1498,6 +1553,12 @@ def SwiftIndirectResult : ParameterABIAttr {
let Documentation = [SwiftIndirectResultDocs];
}
def Suppress : StmtAttr {
let Spellings = [CXX11<"gsl", "suppress">];
let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
let Documentation = [SuppressDocs];
}
def SysVABI : InheritableAttr {
let Spellings = [GCC<"sysv_abi">];
// let Subjects = [Function, ObjCMethod];
@ -1681,6 +1742,7 @@ def Visibility : InheritableAttr {
let Args = [EnumArgument<"Visibility", "VisibilityType",
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
let MeaningfulToClassTemplateDefinition = 1;
let Documentation = [Undocumented];
}

View File

@ -244,6 +244,36 @@ An example of how to use ``alloc_size``
}];
}
def AllocAlignDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Use ``__attribute__((alloc_align(<alignment>))`` on a function
declaration to specify that the return value of the function (which must be a
pointer type) is at least as aligned as the value of the indicated parameter. The
parameter is given by its index in the list of formal parameters; the first
parameter has index 1 unless the function is a C++ non-static member function,
in which case the first parameter has index 2 to account for the implicit ``this``
parameter.
.. code-block:: c++
// The returned pointer has the alignment specified by the first parameter.
void *a(size_t align) __attribute__((alloc_align(1)));
// The returned pointer has the alignment specified by the second parameter.
void *b(void *v, size_t align) __attribute__((alloc_align(2)));
// The returned pointer has the alignment specified by the second visible
// parameter, however it must be adjusted for the implicit 'this' parameter.
void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3)));
Note that this attribute merely informs the compiler that a function always
returns a sufficiently aligned pointer. It does not cause the compiler to
emit code to enforce that alignment. The behavior is undefined if the returned
poitner is not sufficiently aligned.
}];
}
def EnableIfDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@ -960,6 +990,63 @@ When one method overrides another, the overriding method can be more widely avai
}];
}
def ExternalSourceSymbolDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``external_source_symbol`` attribute specifies that a declaration originates
from an external source and describes the nature of that source.
The fact that Clang is capable of recognizing declarations that were defined
externally can be used to provide better tooling support for mixed-language
projects or projects that rely on auto-generated code. For instance, an IDE that
uses Clang and that supports mixed-language projects can use this attribute to
provide a correct 'jump-to-definition' feature. For a concrete example,
consider a protocol that's defined in a Swift file:
.. code-block:: swift
@objc public protocol SwiftProtocol {
func method()
}
This protocol can be used from Objective-C code by including a header file that
was generated by the Swift compiler. The declarations in that header can use
the ``external_source_symbol`` attribute to make Clang aware of the fact
that ``SwiftProtocol`` actually originates from a Swift module:
.. code-block:: objc
__attribute__((external_source_symbol(language="Swift",defined_in="module")))
@protocol SwiftProtocol
@required
- (void) method;
@end
Consequently, when 'jump-to-definition' is performed at a location that
references ``SwiftProtocol``, the IDE can jump to the original definition in
the Swift source file rather than jumping to the Objective-C declaration in the
auto-generated header file.
The ``external_source_symbol`` attribute is a comma-separated list that includes
clauses that describe the origin and the nature of the particular declaration.
Those clauses can be:
language=\ *string-literal*
The name of the source language in which this declaration was defined.
defined_in=\ *string-literal*
The name of the source container in which the declaration was defined. The
exact definition of source container is language-specific, e.g. Swift's
source containers are modules, so ``defined_in`` should specify the Swift
module name.
generated_declaration
This declaration was automatically generated by some tool.
The clauses can be specified in any order. The clauses that are listed above are
all optional, but the attribute has to have at least one clause.
}];
}
def RequireConstantInitDocs : Documentation {
let Category = DocCatVariable;
@ -1182,6 +1269,33 @@ The semantics are as follows:
}];
}
def AVRInterruptDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
AVR targets. This attribute may be attached to a function definition and instructs
the backend to generate appropriate function entry/exit code so that it can be used
directly as an interrupt service routine.
On the AVR, the hardware globally disables interrupts when an interrupt is executed.
The first instruction of an interrupt handler declared with this attribute is a SEI
instruction to re-enable interrupts. See also the signal attribute that
does not insert a SEI instruction.
}];
}
def AVRSignalDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the GNU style ``__attribute__((signal))`` attribute on
AVR targets. This attribute may be attached to a function definition and instructs
the backend to generate appropriate function entry/exit code so that it can be used
directly as an interrupt service routine.
Interrupt handler functions defined with the signal attribute do not re-enable interrupts.
}];
}
def TargetDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@ -1879,6 +1993,55 @@ manipulating bits of the enumerator when issuing warnings.
}];
}
def EnumExtensibilityDocs : Documentation {
let Category = DocCatType;
let Content = [{
Attribute ``enum_extensibility`` is used to distinguish between enum definitions
that are extensible and those that are not. The attribute can take either
``closed`` or ``open`` as an argument. ``closed`` indicates a variable of the
enum type takes a value that corresponds to one of the enumerators listed in the
enum definition or, when the enum is annotated with ``flag_enum``, a value that
can be constructed using values corresponding to the enumerators. ``open``
indicates a variable of the enum type can take any values allowed by the
standard and instructs clang to be more lenient when issuing warnings.
.. code-block:: c
enum __attribute__((enum_extensibility(closed))) ClosedEnum {
A0, A1
};
enum __attribute__((enum_extensibility(open))) OpenEnum {
B0, B1
};
enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum {
C0 = 1 << 0, C1 = 1 << 1
};
enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum {
D0 = 1 << 0, D1 = 1 << 1
};
void foo1() {
enum ClosedEnum ce;
enum OpenEnum oe;
enum ClosedFlagEnum cfe;
enum OpenFlagEnum ofe;
ce = A1; // no warnings
ce = 100; // warning issued
oe = B1; // no warnings
oe = 100; // no warnings
cfe = C0 | C1; // no warnings
cfe = C0 | C1 | 4; // warning issued
ofe = D0 | D1; // no warnings
ofe = D0 | D1 | 4; // no warnings
}
}];
}
def EmptyBasesDocs : Documentation {
let Category = DocCatType;
let Content = [{
@ -2638,6 +2801,32 @@ optimizations like C++'s named return value optimization (NRVO).
}];
}
def SuppressDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
The ``[[gsl::suppress]]`` attribute suppresses specific
clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable
way. The attribute can be attached to declarations, statements, and at
namespace scope.
.. code-block:: c++
[[gsl::suppress("Rh-public")]]
void f_() {
int *p;
[[gsl::suppress("type")]] {
p = reinterpret_cast<int*>(7);
}
}
namespace N {
[[clang::suppress("type", "bounds")]];
...
}
.. _`C++ Core Guidelines`: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement
}];
}
def AbiTagsDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@ -2777,13 +2966,15 @@ See the RenderScript_ documentation for more information.
def XRayDocs : Documentation {
let Category = DocCatFunction;
let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument)";
let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args)";
let Content = [{
``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching.
Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points.
If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise.
``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported.
}];
}

View File

@ -756,11 +756,11 @@ LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset, "UcLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
@ -773,6 +773,7 @@ LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
// Microsoft library builtins.
LIBBUILTIN(_setjmpex, "iJ", "fj", "setjmpex.h", ALL_MS_LANGUAGES)
@ -1086,9 +1087,11 @@ LIBBUILTIN(ilogb, "id", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(lgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(lgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(lgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
// POSIX math.h declares a global, signgam, that lgamma writes to, so these
// shouldn't have "e" or "c" attributes
LIBBUILTIN(lgamma, "dd", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(lgammaf, "ff", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(lgammal, "LdLd", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES)
@ -1362,7 +1365,7 @@ BUILTIN(__builtin_coro_free, "v*v*", "n")
BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n")
BUILTIN(__builtin_coro_alloc, "b", "n")
BUILTIN(__builtin_coro_begin, "v*v*", "n")
BUILTIN(__builtin_coro_end, "vv*Ib", "n")
BUILTIN(__builtin_coro_end, "bv*Ib", "n")
BUILTIN(__builtin_coro_suspend, "cIb", "n")
BUILTIN(__builtin_coro_param, "bv*v*", "n")
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.

View File

@ -35,8 +35,14 @@ BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc")
//===----------------------------------------------------------------------===//
// Instruction builtins.
//===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_s_getreg, "UiIi", "n")
BUILTIN(__builtin_amdgcn_s_waitcnt, "vIi", "n")
BUILTIN(__builtin_amdgcn_s_sendmsg, "vIiUi", "n")
BUILTIN(__builtin_amdgcn_s_sendmsghalt, "vIiUi", "n")
BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n")
BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n")
BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
@ -80,6 +86,11 @@ BUILTIN(__builtin_amdgcn_sicmpl, "LUiLiLiIi", "nc")
BUILTIN(__builtin_amdgcn_fcmp, "LUiddIi", "nc")
BUILTIN(__builtin_amdgcn_fcmpf, "LUiffIi", "nc")
BUILTIN(__builtin_amdgcn_ds_swizzle, "iiIi", "nc")
BUILTIN(__builtin_amdgcn_ds_permute, "iii", "nc")
BUILTIN(__builtin_amdgcn_ds_bpermute, "iii", "nc")
BUILTIN(__builtin_amdgcn_readfirstlane, "ii", "nc")
BUILTIN(__builtin_amdgcn_readlane, "iii", "nc")
BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc")
//===----------------------------------------------------------------------===//
// VI+ only builtins.
@ -96,6 +107,13 @@ TARGET_BUILTIN(__builtin_amdgcn_frexp_exph, "sh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
//===----------------------------------------------------------------------===//
// GFX9+ only builtins.
//===----------------------------------------------------------------------===//
TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
//===----------------------------------------------------------------------===//
// Special builtins.

View File

@ -64,24 +64,10 @@ BUILTIN(__nvvm_read_ptx_sreg_pm3, "i", "n")
// MISC
BUILTIN(__nvvm_clz_i, "ii", "")
BUILTIN(__nvvm_clz_ll, "iLLi", "")
BUILTIN(__nvvm_popc_i, "ii", "")
BUILTIN(__nvvm_popc_ll, "iLLi", "")
BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
// Min Max
BUILTIN(__nvvm_min_i, "iii", "")
BUILTIN(__nvvm_min_ui, "UiUiUi", "")
BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "")
BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "")
BUILTIN(__nvvm_max_i, "iii", "")
BUILTIN(__nvvm_max_ui, "UiUiUi", "")
BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "")
BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "")
BUILTIN(__nvvm_fmax_ftz_f, "fff", "")
BUILTIN(__nvvm_fmax_f, "fff", "")
BUILTIN(__nvvm_fmin_ftz_f, "fff", "")
@ -133,11 +119,6 @@ BUILTIN(__nvvm_div_rz_d, "ddd", "")
BUILTIN(__nvvm_div_rm_d, "ddd", "")
BUILTIN(__nvvm_div_rp_d, "ddd", "")
// Brev
BUILTIN(__nvvm_brev32, "UiUi", "")
BUILTIN(__nvvm_brev64, "ULLiULLi", "")
// Sad
BUILTIN(__nvvm_sad_i, "iiii", "")
@ -155,9 +136,6 @@ BUILTIN(__nvvm_ceil_d, "dd", "")
// Abs
BUILTIN(__nvvm_abs_i, "ii", "")
BUILTIN(__nvvm_abs_ll, "LLiLLi", "")
BUILTIN(__nvvm_fabs_ftz_f, "ff", "")
BUILTIN(__nvvm_fabs_f, "ff", "")
BUILTIN(__nvvm_fabs_d, "dd", "")
@ -385,8 +363,6 @@ BUILTIN(__nvvm_ull2d_rp, "dULLi", "")
BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
BUILTIN(__nvvm_f2h_rn, "Usf", "")
BUILTIN(__nvvm_h2f, "fUs", "")
// Bitcast
BUILTIN(__nvvm_bitcast_f2i, "if", "")

View File

@ -16,9 +16,9 @@
// The format of this database matches clang/Basic/Builtins.def.
// Note that current_memory is not "c" (readnone) because it must be sequenced with
// respect to grow_memory calls.
// Note that current_memory is not "c" (readnone) because it must be sequenced
// with respect to grow_memory calls.
BUILTIN(__builtin_wasm_current_memory, "z", "n")
BUILTIN(__builtin_wasm_grow_memory, "vz", "n")
BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
#undef BUILTIN

View File

@ -391,7 +391,6 @@ TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLiC*", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "", "sse4.1")
@ -576,7 +575,6 @@ TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLiC*", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "", "avx2")
@ -832,8 +830,6 @@ TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "", "xop")
TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "", "xop")
@ -997,22 +993,22 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "",
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "", "avx512f")
@ -1068,10 +1064,10 @@ TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packsswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packusdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packuswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
@ -1590,27 +1586,15 @@ TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastmb512, "V8LLiUc","","avx512cd")
TARGET_BUILTIN(__builtin_ia32_broadcastmw512, "V16iUs","","avx512cd")
TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_512, "V16fV4fV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_broadcastf64x4_512, "V8dV4dV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_512, "V16iV4iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_broadcasti64x4_512, "V8LLiV4LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_broadcastmb128, "V2LLiUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastmb256, "V4LLiUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastmw128, "V4iUs","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastmw256, "V8iUs","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_512_mask, "V16fV4fV16fUs","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_broadcastf32x8_512_mask, "V16fV8fV16fUs","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_512_mask, "V8dV2dV8dUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_512_mask, "V16iV4iV16iUs","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_broadcasti32x8_512_mask, "V16iV8iV16iUs","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_512_mask, "V8LLiV2LLiV8LLiUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_256_mask, "V8fV4fV8fUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_256_mask, "V4dV2dV4dUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_128_mask, "V4iV4iV4iUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_256_mask, "V8iV4iV8iUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_256_mask, "V4LLiV2LLiV4LLiUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_256_mask, "V8fV4fV8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_256_mask, "V8iV4iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastw512_gpr_mask, "V32shV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_pbroadcastw256_gpr_mask, "V16shV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastw128_gpr_mask, "V8ssV8sUc","","avx512bw,avx512vl")
@ -1761,7 +1745,6 @@ TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movntdqa512, "V8LLiV8LLi*","","avx512f")
TARGET_BUILTIN(__builtin_ia32_palignr512_mask, "V64cV64cV64cIiV64cULLi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128_mask, "V8sV16cV16cIiV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256_mask, "V16sV32cV32cIiV16sUs","","avx512bw,avx512vl")
@ -1826,6 +1809,9 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "")
TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx")
TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx")
// CLZERO
TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero")
// MSVC
TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@ -1840,6 +1826,18 @@ TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readfsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readfsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readfsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readfsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readgsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readgsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readgsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readgsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef TARGET_BUILTIN

View File

@ -45,6 +45,7 @@ def Named : Decl<1>;
def ObjCAtDefsField : DDecl<Field>;
def MSProperty : DDecl<Declarator>;
def Function : DDecl<Declarator>, DeclContext;
def CXXDeductionGuide : DDecl<Function>;
def CXXMethod : DDecl<Function>;
def CXXConstructor : DDecl<CXXMethod>;
def CXXDestructor : DDecl<CXXMethod>;

View File

@ -29,6 +29,7 @@
#include <cassert>
#include <cstdint>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
@ -222,6 +223,9 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
void setMapping(diag::kind Diag, DiagnosticMapping Info) {
DiagMap[Diag] = Info;
}
DiagnosticMapping lookupMapping(diag::kind Diag) const {
return DiagMap.lookup(Diag);
}
DiagnosticMapping &getOrAddMapping(diag::kind Diag);
@ -232,59 +236,97 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// \brief Keeps and automatically disposes all DiagStates that we create.
std::list<DiagState> DiagStates;
/// \brief Represents a point in source where the diagnostic state was
/// modified because of a pragma.
///
/// 'Loc' can be null if the point represents the diagnostic state
/// modifications done through the command-line.
struct DiagStatePoint {
DiagState *State;
FullSourceLoc Loc;
DiagStatePoint(DiagState *State, FullSourceLoc Loc)
: State(State), Loc(Loc) { }
bool operator<(const DiagStatePoint &RHS) const {
// If Loc is invalid it means it came from <command-line>, in which case
// we regard it as coming before any valid source location.
if (RHS.Loc.isInvalid())
return false;
if (Loc.isInvalid())
return true;
return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
/// A mapping from files to the diagnostic states for those files. Lazily
/// built on demand for files in which the diagnostic state has not changed.
class DiagStateMap {
public:
/// Add an initial diagnostic state.
void appendFirst(DiagState *State);
/// Add a new latest state point.
void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
/// Look up the diagnostic state at a given source location.
DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
/// Determine whether this map is empty.
bool empty() const { return Files.empty(); }
/// Clear out this map.
void clear() {
Files.clear();
FirstDiagState = CurDiagState = nullptr;
CurDiagStateLoc = SourceLocation();
}
/// Grab the most-recently-added state point.
DiagState *getCurDiagState() const { return CurDiagState; }
/// Get the location at which a diagnostic state was last added.
SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
private:
/// \brief Represents a point in source where the diagnostic state was
/// modified because of a pragma.
///
/// 'Loc' can be null if the point represents the diagnostic state
/// modifications done through the command-line.
struct DiagStatePoint {
DiagState *State;
unsigned Offset;
DiagStatePoint(DiagState *State, unsigned Offset)
: State(State), Offset(Offset) { }
};
/// Description of the diagnostic states and state transitions for a
/// particular FileID.
struct File {
/// The diagnostic state for the parent file. This is strictly redundant,
/// as looking up the DecomposedIncludedLoc for the FileID in the Files
/// map would give us this, but we cache it here for performance.
File *Parent = nullptr;
/// The offset of this file within its parent.
unsigned ParentOffset = 0;
/// Whether this file has any local (not imported from an AST file)
/// diagnostic state transitions.
bool HasLocalTransitions = false;
/// The points within the file where the state changes. There will always
/// be at least one of these (the state on entry to the file).
llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
DiagState *lookup(unsigned Offset) const;
};
/// The diagnostic states for each file.
mutable std::map<FileID, File> Files;
/// The initial diagnostic state.
DiagState *FirstDiagState;
/// The current diagnostic state.
DiagState *CurDiagState;
/// The location at which the current diagnostic state was established.
SourceLocation CurDiagStateLoc;
/// Get the diagnostic state information for a file.
File *getFile(SourceManager &SrcMgr, FileID ID) const;
friend class ASTReader;
friend class ASTWriter;
};
/// \brief A sorted vector of all DiagStatePoints representing changes in
/// diagnostic state due to diagnostic pragmas.
///
/// The vector is always sorted according to the SourceLocation of the
/// DiagStatePoint.
typedef std::vector<DiagStatePoint> DiagStatePointsTy;
mutable DiagStatePointsTy DiagStatePoints;
DiagStateMap DiagStatesByLoc;
/// \brief Keeps the DiagState that was active during each diagnostic 'push'
/// so we can get back at it when we 'pop'.
std::vector<DiagState *> DiagStateOnPushStack;
DiagState *GetCurDiagState() const {
assert(!DiagStatePoints.empty());
return DiagStatePoints.back().State;
return DiagStatesByLoc.getCurDiagState();
}
void PushDiagStatePoint(DiagState *State, SourceLocation L) {
FullSourceLoc Loc(L, getSourceManager());
// Make sure that DiagStatePoints is always sorted according to Loc.
assert(Loc.isValid() && "Adding invalid loc point");
assert(!DiagStatePoints.empty() &&
(DiagStatePoints.back().Loc.isInvalid() ||
DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
"Previous point loc comes after or is the same as new one");
DiagStatePoints.push_back(DiagStatePoint(State, Loc));
}
void PushDiagStatePoint(DiagState *State, SourceLocation L);
/// \brief Finds the DiagStatePoint that contains the diagnostic state of
/// the given source location.
DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
: DiagStatesByLoc.getCurDiagState();
}
/// \brief Sticky flag set to \c true when an error is emitted.
bool ErrorOccurred;
@ -390,7 +432,11 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
assert(SourceMgr && "SourceManager not set!");
return *SourceMgr;
}
void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
void setSourceManager(SourceManager *SrcMgr) {
assert(DiagStatesByLoc.empty() &&
"Leftover diag state from a different SourceManager.");
SourceMgr = SrcMgr;
}
//===--------------------------------------------------------------------===//
// DiagnosticsEngine characterization methods, used by a client to customize

View File

@ -44,7 +44,8 @@ def note_constexpr_non_global : Note<
def note_constexpr_uninitialized : Note<
"%select{|sub}0object of type %1 is not initialized">;
def note_constexpr_array_index : Note<"cannot refer to element %0 of "
"%select{array of %2 elements|non-array object}1 in a constant expression">;
"%select{array of %2 element%plural{1:|:s}2|non-array object}1 "
"in a constant expression">;
def note_constexpr_float_arithmetic : Note<
"floating point arithmetic produces %select{an infinity|a NaN}0">;
def note_constexpr_pointer_subtraction_not_same_array : Note<

View File

@ -45,7 +45,9 @@ def err_expected_colon_after_setter_name : Error<
"must end with ':'">;
def err_expected_string_literal : Error<"expected string literal "
"%select{in %1|for diagnostic message in static_assert|"
"for optional message in 'availability' attribute}0">;
"for optional message in 'availability' attribute|"
"for %select{language|source container}1 name in "
"'external_source_symbol' attribute}0">;
def err_invalid_string_udl : Error<
"string literal with user-defined suffix cannot be used here">;
def err_invalid_character_udl : Error<
@ -88,10 +90,10 @@ def err_module_unavailable : Error<
"module '%0' %select{is incompatible with|requires}1 feature '%2'">;
def err_module_header_missing : Error<
"%select{|umbrella }0header '%1' not found">;
def err_module_lock_failure : Error<
"could not acquire lock file for module '%0': %1">, DefaultFatal;
def err_module_lock_timeout : Error<
"timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
def remark_module_lock_failure : Remark<
"could not acquire lock file for module '%0': %1">, InGroup<ModuleBuild>;
def remark_module_lock_timeout : Remark<
"timed out waiting to acquire lock file for module '%0'">, InGroup<ModuleBuild>;
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
DefaultFatal;
def err_module_prebuilt : Error<

View File

@ -85,6 +85,8 @@ def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
"the clang compiler does not support '%0' for C++ on Darwin/i386">;
def err_drv_clang_unsupported_opt_faltivec : Error<
"the clang compiler does not support '%0', %1">;
def err_drv_command_failed : Error<
"%0 command failed with exit code %1 (use -v to see invocation)">;
def err_drv_compilationdatabase : Error<
@ -92,7 +94,7 @@ def err_drv_compilationdatabase : Error<
def err_drv_command_signalled : Error<
"%0 command failed due to signal (use -v to see invocation)">;
def err_drv_force_crash : Error<
"failing because environment variable '%0' is set">;
"failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
def err_drv_invalid_mfloat_abi : Error<
"invalid float ABI '%0'">;
def err_drv_invalid_libcxx_deployment : Error<
@ -133,6 +135,7 @@ def err_drv_invalid_gcc_output_type : Error<
"invalid output type '%0' for use with gcc tool">;
def err_drv_cc_print_options_failure : Error<
"unable to open CC_PRINT_OPTIONS file: %0">;
def err_drv_lto_without_lld : Error<"LTO requires -fuse-ld=lld">;
def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
def err_drv_conflicting_deployment_targets : Error<
@ -230,6 +233,7 @@ def note_drv_t_option_is_global : Note<
"The last /TC or /TP option takes precedence over earlier instances">;
def note_drv_address_sanitizer_debug_runtime : Note<
"AddressSanitizer doesn't support linking with debug runtime libraries yet">;
def note_drv_use_standard : Note<"use '%0' for '%1' standard">;
def err_analyzer_config_no_value : Error<
"analyzer-config option '%0' has a key but no value">;
@ -247,6 +251,10 @@ def err_test_module_file_extension_format : Error<
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
InGroup<Fallback>;
def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
InGroup<DiagGroup<"slash-u-filename">>;
def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">;
def err_drv_ropi_rwpi_incompatible_with_pic : Error<
"embedded and GOT-based position independence are incompatible">;
def err_drv_ropi_incompatible_with_cxx : Error<
@ -277,4 +285,8 @@ def warn_drv_ps4_sdk_dir : Warning<
def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
def err_drv_defsym_invalid_format : Error<"defsym must be of the form: sym=value: %0">;
def err_drv_defsym_invalid_symval : Error<"Value is not an integer: %0">;
def warn_drv_msvc_not_found : Warning<
"unable to find a Visual Studio installation; "
"try running Clang from a developer command prompt">,
InGroup<DiagGroup<"msvc-not-found">>;
}

View File

@ -34,7 +34,9 @@ def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
def BitFieldWidth : DiagGroup<"bitfield-width">;
def Coroutine : DiagGroup<"coroutine">;
def ConstantConversion :
DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
def LiteralConversion : DiagGroup<"literal-conversion">;
@ -175,6 +177,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
def CXX11WarnOverrideDestructor :
DiagGroup<"inconsistent-missing-destructor-override">;
def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
// Original name of this warning in Clang
@ -355,6 +359,7 @@ def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def Sentinel : DiagGroup<"sentinel">;
def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
def ShadowField : DiagGroup<"shadow-field">;
def ShadowFieldInConstructorModified : DiagGroup<"shadow-field-in-constructor-modified">;
def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor",
[ShadowFieldInConstructorModified]>;
@ -366,7 +371,7 @@ def ShadowUncapturedLocal : DiagGroup<"shadow-uncaptured-local">;
def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified,
ShadowIvar]>;
def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
ShadowUncapturedLocal]>;
ShadowUncapturedLocal, ShadowField]>;
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">;
@ -480,6 +485,7 @@ def UnusedFunction : DiagGroup<"unused-function", [UnneededInternalDecl]>;
def UnusedMemberFunction : DiagGroup<"unused-member-function",
[UnneededMemberFunction]>;
def UnusedLabel : DiagGroup<"unused-label">;
def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">;
def UnusedParameter : DiagGroup<"unused-parameter">;
def UnusedResult : DiagGroup<"unused-result">;
def PotentiallyEvaluatedExpression : DiagGroup<"potentially-evaluated-expression">;
@ -602,6 +608,7 @@ def Conversion : DiagGroup<"conversion",
[BoolConversion,
ConstantConversion,
EnumConversion,
BitFieldEnumConversion,
FloatConversion,
Shorten64To32,
IntConversion,
@ -617,8 +624,9 @@ def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
// UnusedParameter, (matches GCC's behavior)
// UnusedMemberFunction, (clean-up llvm before enabling)
UnusedPrivateField, UnusedLocalTypedef,
UnusedValue, UnusedVariable, UnusedPropertyIvar]>,
UnusedPrivateField, UnusedLambdaCapture,
UnusedLocalTypedef, UnusedValue, UnusedVariable,
UnusedPropertyIvar]>,
DiagCategory<"Unused Entity Issue">;
// Format settings.
@ -881,7 +889,7 @@ def BackendOptimizationFailure : DiagGroup<"pass-failed">;
def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
// AddressSanitizer frontent instrumentation remarks.
// AddressSanitizer frontend instrumentation remarks.
def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
// Issues with serialized diagnostics.

View File

@ -84,6 +84,7 @@ class DiagnosticMapping {
unsigned IsPragma : 1;
unsigned HasNoWarningAsError : 1;
unsigned HasNoErrorAsFatal : 1;
unsigned WasUpgradedFromWarning : 1;
public:
static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
@ -94,6 +95,7 @@ class DiagnosticMapping {
Result.IsPragma = IsPragma;
Result.HasNoWarningAsError = 0;
Result.HasNoErrorAsFatal = 0;
Result.WasUpgradedFromWarning = 0;
return Result;
}
@ -103,11 +105,33 @@ class DiagnosticMapping {
bool isUser() const { return IsUser; }
bool isPragma() const { return IsPragma; }
bool isErrorOrFatal() const {
return getSeverity() == diag::Severity::Error ||
getSeverity() == diag::Severity::Fatal;
}
bool hasNoWarningAsError() const { return HasNoWarningAsError; }
void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
/// Whether this mapping attempted to map the diagnostic to a warning, but
/// was overruled because the diagnostic was already mapped to an error or
/// fatal error.
bool wasUpgradedFromWarning() const { return WasUpgradedFromWarning; }
void setUpgradedFromWarning(bool Value) { WasUpgradedFromWarning = Value; }
/// Serialize the bits that aren't based on context.
unsigned serializeBits() const {
return (WasUpgradedFromWarning << 3) | Severity;
}
static diag::Severity deserializeSeverity(unsigned Bits) {
return (diag::Severity)(Bits & 0x7);
}
static bool deserializeUpgradedFromWarning(unsigned Bits) {
return Bits >> 3;
}
};
/// \brief Used for handling and querying diagnostic IDs.

View File

@ -176,6 +176,9 @@ def warn_gcc_attribute_location : Warning<
def warn_attribute_no_decl : Warning<
"attribute %0 ignored, because it is not attached to a declaration">,
InGroup<IgnoredAttributes>;
def err_ms_attributes_not_enabled : Error<
"'__declspec' attributes are not enabled; use '-fdeclspec' or "
"'-fms-extensions' to enable support for __declspec attributes">;
def err_expected_method_body : Error<"expected method body">;
def err_declspec_after_virtspec : Error<
"'%0' qualifier may not appear after the virtual specifier '%1'">;
@ -361,8 +364,6 @@ def ext_decomp_decl_empty : ExtWarn<
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
"method type specifier must start with '-' or '+'">;
def err_objc_no_attributes_on_category : Error<
"attributes may not be specified on a category">;
def err_objc_missing_end : Error<"missing '@end'">;
def note_objc_container_start : Note<
"%select{class|protocol|category|class extension|implementation"
@ -435,6 +436,13 @@ def err_declaration_does_not_declare_param : Error<
"declaration does not declare a parameter">;
def err_no_matching_param : Error<"parameter named %0 is missing">;
/// Objective-C++ parser diagnostics
def err_expected_token_instead_of_objcxx_keyword : Error<
"expected %0; %1 is a keyword in Objective-C++">;
def err_expected_member_name_or_semi_objcxx_keyword : Error<
"expected member name or ';' after declaration specifiers; "
"%0 is a keyword in Objective-C++">;
/// C++ parser diagnostics
def err_invalid_operator_on_type : Error<
"cannot use %select{dot|arrow}0 operator on a type">;
@ -669,9 +677,6 @@ def warn_static_inline_explicit_inst_ignored : Warning<
// Constructor template diagnostics.
def err_out_of_line_constructor_template_id : Error<
"out-of-line constructor for %0 cannot have template arguments">;
def err_out_of_line_template_id_type_names_constructor : Error<
"qualified reference to %0 is a constructor name rather than a "
"%select{template name|type}1 wherever a constructor can be declared">;
def err_expected_qualified_after_typename : Error<
"expected a qualified name after 'typename'">;
@ -859,6 +864,12 @@ def err_availability_query_repeated_platform: Error<
def err_availability_query_repeated_star : Error<
"'*' query has already been specified">;
// External source symbol attribute
def err_external_source_symbol_expected_keyword : Error<
"expected 'language', 'defined_in', or 'generated_declaration'">;
def err_external_source_symbol_duplicate_clause : Error<
"duplicate %0 clause in an 'external_source_symbol' attribute">;
// Type safety attributes
def err_type_safety_unknown_flag : Error<
"invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
@ -1036,6 +1047,16 @@ def err_pragma_loop_missing_argument : Error<
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
"vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">;
def err_pragma_fp_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
def err_pragma_fp_invalid_argument : Error<
"unexpected argument '%0' to '#pragma clang fp %1'; "
"expected 'on', 'fast' or 'off'">;
def err_pragma_fp_scope : Error<
"'#pragma clang fp' can only appear at file scope or at the start of a "
"compound statement">;
def err_pragma_invalid_keyword : Error<
"invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;

View File

@ -259,6 +259,9 @@ def err_anyx86_interrupt_attribute : Error<
"a pointer as the first parameter|a %2 type as the second parameter}1">;
def err_anyx86_interrupt_called : Error<
"interrupt service routine cannot be called directly">;
def warn_arm_interrupt_calling_convention : Warning<
"call to function without interrupt attribute could clobber interruptee's VFP registers">,
InGroup<Extra>;
def warn_mips_interrupt_attribute : Warning<
"MIPS 'interrupt' attribute only applies to functions that have "
"%select{no parameters|a 'void' return type}0">,
@ -316,6 +319,9 @@ def warn_unneeded_member_function : Warning<
InGroup<UnneededMemberFunction>, DefaultIgnore;
def warn_unused_private_field: Warning<"private field %0 is not used">,
InGroup<UnusedPrivateField>, DefaultIgnore;
def warn_unused_lambda_capture: Warning<"lambda capture %0 is not "
"%select{used|required to be captured for this use}1">,
InGroup<UnusedLambdaCapture>, DefaultIgnore;
def warn_parameter_size: Warning<
"%0 is a large (%1 bytes) pass-by-value argument; "
@ -363,7 +369,9 @@ def warn_decl_shadow :
"local variable|"
"variable in %2|"
"static data member of %2|"
"field of %2}1">,
"field of %2|"
"typedef in %2|"
"type alias in %2}1">,
InGroup<Shadow>, DefaultIgnore;
def warn_decl_shadow_uncaptured_local :
Warning<warn_decl_shadow.Text>,
@ -1201,8 +1209,9 @@ def warn_cxx98_compat_unelaborated_friend_type : Warning<
def err_qualified_friend_not_found : Error<
"no function named %0 with type %1 was found in the specified scope">;
def err_introducing_special_friend : Error<
"must use a qualified name when declaring a %select{constructor|"
"destructor|conversion operator}0 as a friend">;
"%plural{[0,2]:must use a qualified name when declaring|3:cannot declare}0"
" a %select{constructor|destructor|conversion operator|deduction guide}0 "
"as a friend">;
def err_tagless_friend_type_template : Error<
"friend type templates must use an elaborated type">;
def err_no_matching_local_friend : Error<
@ -1447,6 +1456,15 @@ def err_nested_name_spec_is_not_class : Error<
def ext_nested_name_spec_is_enum : ExtWarn<
"use of enumeration in a nested name specifier is a C++11 extension">,
InGroup<CXX11>;
def err_out_of_line_qualified_id_type_names_constructor : Error<
"qualified reference to %0 is a constructor name rather than a "
"%select{template name|type}1 in this context">;
def ext_out_of_line_qualified_id_type_names_constructor : ExtWarn<
"ISO C++ specifies that "
"qualified reference to %0 is a constructor name rather than a "
"%select{template name|type}1 in this context, despite preceding "
"%select{'typename'|'template'}2 keyword">, SFINAEFailure,
InGroup<DiagGroup<"injected-class-name">>;
// C++ class members
def err_storageclass_invalid_for_member : Error<
@ -1608,7 +1626,14 @@ def err_covariant_return_type_class_type_more_qualified : Error<
"return type of virtual function %0 is not covariant with the return type of "
"the function it overrides (class type %1 is more qualified than class "
"type %2">;
// C++ implicit special member functions
def note_in_declaration_of_implicit_special_member : Note<
"while declaring the implicit "
"%select{default constructor|copy constructor|move constructor|"
"copy assignment operator|move assignment operator|destructor}1"
" for %0">;
// C++ constructors
def err_constructor_cannot_be : Error<"constructor cannot be declared '%0'">;
def err_invalid_qualified_constructor : Error<
@ -1664,8 +1689,8 @@ def err_init_conversion_failed : Error<
"cannot initialize %select{a variable|a parameter|return object|an "
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|a constructor delegation|a vector element|a block element|a "
"complex element|a lambda capture|a compound literal initializer|a "
"related result|a parameter of CF audited function}0 "
"block element|a complex element|a lambda capture|a compound literal "
"initializer|a related result|a parameter of CF audited function}0 "
"%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
"with an %select{rvalue|lvalue}2 of incompatible type}1,3"
"%select{|: different classes%diff{ ($ vs $)|}5,6"
@ -1791,8 +1816,9 @@ def note_uninit_fixit_remove_cond : Note<
"remove the %select{'%1' if its condition|condition if it}0 "
"is always %select{false|true}2">;
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
def err_list_init_in_parens : Error<"list-initializer for non-class type %0 "
"must not be parenthesized">;
def err_list_init_in_parens : Error<
"cannot initialize %select{non-class|reference}0 type %1 with a "
"parenthesized initializer list">;
def warn_unsequenced_mod_mod : Warning<
"multiple unsequenced modifications to %0">, InGroup<Unsequenced>;
@ -1833,8 +1859,8 @@ def warn_cxx98_compat_temp_copy : Warning<
InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
def err_selected_explicit_constructor : Error<
"chosen constructor is explicit in copy-initialization">;
def note_constructor_declared_here : Note<
"constructor declared here">;
def note_explicit_ctor_deduction_guide_here : Note<
"explicit %select{constructor|deduction guide}0 declared here">;
// C++11 decltype
def err_decltype_in_declarator : Error<
@ -1845,8 +1871,8 @@ def warn_cxx98_compat_auto_type_specifier : Warning<
"'auto' type specifier is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_auto_variable_cannot_appear_in_own_initializer : Error<
"variable %0 declared with %select{'auto'|'decltype(auto)'|'__auto_type'}1 "
"type cannot appear in its own initializer">;
"variable %0 declared with deduced type %1 "
"cannot appear in its own initializer">;
def err_binding_cannot_appear_in_own_initializer : Error<
"binding %0 cannot appear in the initializer of its own "
"decomposition declaration">;
@ -1855,20 +1881,29 @@ def err_illegal_decl_array_of_auto : Error<
def err_new_array_of_auto : Error<
"cannot allocate array of 'auto'">;
def err_auto_not_allowed : Error<
"%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed "
"%select{'auto'|'decltype(auto)'|'__auto_type'|"
"use of "
"%select{class template|function template|variable template|alias template|"
"template template parameter|template}2 %3 requires template arguments; "
"argument deduction}0 not allowed "
"%select{in function prototype"
"|in non-static struct member|in struct member"
"|in non-static union member|in union member"
"|in non-static class member|in interface member"
"|in exception declaration|in template parameter|in block literal"
"|in exception declaration|in template parameter until C++1z|in block literal"
"|in template argument|in typedef|in type alias|in function return type"
"|in conversion function type|here|in lambda parameter"
"|in type allocated by 'new'|in K&R-style function parameter}1"
"%select{|||||||| until C++1z||||||||||}1">;
"|in type allocated by 'new'|in K&R-style function parameter"
"|in template parameter|in friend declaration}1">;
def err_dependent_deduced_tst : Error<
"typename specifier refers to "
"%select{class template|function template|variable template|alias template|"
"template template parameter|template}0 member in %1; "
"argument deduction not allowed here">;
def err_auto_not_allowed_var_inst : Error<
"'auto' variable template instantiation is not allowed">;
def err_auto_var_requires_init : Error<
"declaration of variable %0 with type %1 requires an initializer">;
"declaration of variable %0 with deduced type %1 requires an initializer">;
def err_auto_new_requires_ctor_arg : Error<
"new expression for type %0 requires a constructor argument">;
def err_auto_new_list_init : Error<
@ -1898,8 +1933,13 @@ def err_auto_var_deduction_failure_from_init_list : Error<
def err_auto_new_deduction_failure : Error<
"new expression for type %0 has incompatible constructor argument of type %1">;
def err_auto_different_deductions : Error<
"'%select{auto|decltype(auto)|__auto_type}0' deduced as %1 in declaration "
"of %2 and deduced as %3 in declaration of %4">;
"%select{'auto'|'decltype(auto)'|'__auto_type'|template arguments}0 "
"deduced as %1 in declaration of %2 and "
"deduced as %3 in declaration of %4">;
def err_auto_non_deduced_not_alone : Error<
"%select{function with deduced return type|"
"declaration with trailing return type}0 "
"must be the only declaration in its group">;
def err_implied_std_initializer_list_not_found : Error<
"cannot deduce type of initializer list because std::initializer_list was "
"not found; include <initializer_list>">;
@ -1915,6 +1955,8 @@ def err_auto_bitfield : Error<
"cannot pass bit-field as __auto_type initializer in C">;
// C++1y decltype(auto) type
def err_decltype_auto_invalid : Error<
"'decltype(auto)' not allowed here">;
def err_decltype_auto_cannot_be_combined : Error<
"'decltype(auto)' cannot be combined with other type specifiers">;
def err_decltype_auto_function_declarator_not_declaration : Error<
@ -1925,6 +1967,56 @@ def err_decltype_auto_compound_type : Error<
def err_decltype_auto_initializer_list : Error<
"cannot deduce 'decltype(auto)' from initializer list">;
// C++1z deduced class template specialization types
def err_deduced_class_template_compound_type : Error<
"cannot %select{form pointer to|form reference to|form array of|"
"form function returning|use parentheses when declaring variable with}0 "
"deduced class template specialization type">;
def err_deduced_non_class_template_specialization_type : Error<
"%select{<error>|function template|variable template|alias template|"
"template template parameter|template}0 %1 requires template arguments; "
"argument deduction only allowed for class templates">;
def err_deduced_class_template_ctor_ambiguous : Error<
"ambiguous deduction for template arguments of %0">;
def err_deduced_class_template_ctor_no_viable : Error<
"no viable constructor or deduction guide for deduction of "
"template arguments of %0">;
def err_deduced_class_template_incomplete : Error<
"template %0 has no definition and no %select{|viable }1deduction guides "
"for deduction of template arguments">;
def err_deduced_class_template_deleted : Error<
"class template argument deduction for %0 selected a deleted constructor">;
def err_deduced_class_template_explicit : Error<
"class template argument deduction for %0 selected an explicit "
"%select{constructor|deduction guide}1 for copy-list-initialization">;
def err_deduction_guide_no_trailing_return_type : Error<
"deduction guide declaration without trailing return type">;
def err_deduction_guide_bad_trailing_return_type : Error<
"deduced type %1 of deduction guide is not %select{|written as }2"
"a specialization of template %0">;
def err_deduction_guide_with_complex_decl : Error<
"cannot specify any part of a return type in the "
"declaration of a deduction guide">;
def err_deduction_guide_invalid_specifier : Error<
"deduction guide cannot be declared '%0'">;
def err_deduction_guide_name_not_class_template : Error<
"cannot specify deduction guide for "
"%select{<error>|function template|variable template|alias template|"
"template template parameter|dependent template name}0 %1">;
def err_deduction_guide_wrong_scope : Error<
"deduction guide must be declared in the same scope as template %q0">;
def err_deduction_guide_defines_function : Error<
"deduction guide cannot have a function definition">;
def err_deduction_guide_explicit_mismatch : Error<
"deduction guide is %select{not |}0declared 'explicit' but "
"previous declaration was%select{ not|}0">;
def err_deduction_guide_specialized : Error<"deduction guide cannot be "
"%select{explicitly instantiated|explicitly specialized}0">;
def err_deduction_guide_template_not_deducible : Error<
"deduction guide template contains "
"%select{a template parameter|template parameters}0 that cannot be "
"deduced">;
// C++1y deduced return types
def err_auto_fn_deduction_failure : Error<
"cannot deduce return type %0 from returned value of type %1">;
@ -1950,6 +2042,9 @@ def override_keyword_hides_virtual_member_function : Error<
"%select{function|functions}1">;
def err_function_marked_override_not_overriding : Error<
"%0 marked 'override' but does not override any member functions">;
def warn_destructor_marked_not_override_overriding : Warning <
"%0 overrides a destructor but is not marked 'override'">,
InGroup<CXX11WarnOverrideDestructor>, DefaultIgnore;
def warn_function_marked_not_override_overriding : Warning <
"%0 overrides a member function but is not marked 'override'">,
InGroup<CXX11WarnOverrideMethod>;
@ -2215,6 +2310,9 @@ def err_concept_specialized : Error<
"%select{function|variable}0 concept cannot be "
"%select{explicitly instantiated|explicitly specialized|partially specialized}1">;
def err_template_different_associated_constraints : Error<
"associated constraints differ in template redeclaration">;
// C++11 char16_t/char32_t
def warn_cxx98_compat_unicode_type : Warning<
"'%0' type specifier is incompatible with C++98">,
@ -2261,7 +2359,7 @@ def warn_unsupported_target_attribute
InGroup<IgnoredAttributes>;
def err_attribute_unsupported
: Error<"%0 attribute is not supported for this target">;
// The err_*_attribute_argument_not_int are seperate because they're used by
// The err_*_attribute_argument_not_int are separate because they're used by
// VerifyIntegerConstantExpression.
def err_aligned_attribute_argument_not_int : Error<
"'aligned' attribute requires integer constant">;
@ -2659,7 +2757,8 @@ def warn_attribute_wrong_decl_type : Warning<
"|functions, methods, enums, and classes"
"|structs, classes, variables, functions, and inline namespaces"
"|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
"|classes and enumerations}1">,
"|classes and enumerations"
"|named declarations}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
@ -3132,7 +3231,8 @@ def err_attribute_regparm_invalid_number : Error<
"'regparm' parameter must be between 0 and %0 inclusive">;
def err_attribute_not_supported_in_lang : Error<
"%0 attribute is not supported in %select{C|C++|Objective-C}1">;
def err_attribute_not_supported_on_arch
: Error<"%0 attribute is not supported on '%1'">;
// Clang-Specific Attributes
def warn_attribute_iboutlet : Warning<
@ -3380,7 +3480,7 @@ def note_ovl_candidate_disabled_by_function_cond_attr : Note<
def note_ovl_candidate_disabled_by_extension : Note<
"candidate disabled due to OpenCL extension">;
def err_addrof_function_disabled_by_enable_if_attr : Error<
"cannot take address of function %0 becuase it has one or more "
"cannot take address of function %0 because it has one or more "
"non-tautological enable_if conditions">;
def note_addrof_ovl_candidate_disabled_by_enable_if_attr : Note<
"candidate function made ineligible by enable_if">;
@ -3789,11 +3889,13 @@ def err_template_decl_ref : Error<
// C++ Template Argument Lists
def err_template_missing_args : Error<
"use of class template %0 requires template arguments">;
"use of "
"%select{class template|function template|variable template|alias template|"
"template template parameter|template}0 %1 requires template arguments">;
def err_template_arg_list_different_arity : Error<
"%select{too few|too many}0 template arguments for "
"%select{class template|function template|template template parameter"
"|template}1 %2">;
"%select{class template|function template|variable template|alias template|"
"template template parameter|template}1 %2">;
def note_template_decl_here : Note<"template is declared here">;
def err_template_arg_must_be_type : Error<
"template argument for template type parameter must be a type">;
@ -4063,7 +4165,7 @@ def ext_partial_specs_not_deducible : ExtWarn<
"%select{a template parameter|template parameters}1 that cannot be "
"deduced; this partial specialization will never be used">,
DefaultError, InGroup<DiagGroup<"unusable-partial-specialization">>;
def note_partial_spec_unused_parameter : Note<
def note_non_deducible_parameter : Note<
"non-deducible template parameter %0">;
def err_partial_spec_ordering_ambiguous : Error<
"ambiguous partial specializations of %0">;
@ -4286,6 +4388,8 @@ def note_typename_refers_here : Note<
"referenced member %0 is declared here">;
def err_typename_missing : Error<
"missing 'typename' prior to dependent type name '%0%1'">;
def err_typename_missing_template : Error<
"missing 'typename' prior to dependent type template name '%0%1'">;
def ext_typename_missing : ExtWarn<
"missing 'typename' prior to dependent type name '%0%1'">,
InGroup<DiagGroup<"typename-missing">>;
@ -4304,7 +4408,7 @@ def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
def err_template_kw_refers_to_class_template : Error<
"'%0%1' instantiated to a class template, not a function template">;
def note_referenced_class_template : Error<
def note_referenced_class_template : Note<
"class template declared here">;
def err_template_kw_missing : Error<
"missing 'template' keyword prior to dependent template name '%0%1'">;
@ -4808,6 +4912,21 @@ def warn_bitfield_width_exceeds_type_width: Warning<
def warn_anon_bitfield_width_exceeds_type_width : Warning<
"width of anonymous bit-field (%0 bits) exceeds width of its type; value "
"will be truncated to %1 bit%s1">, InGroup<BitFieldWidth>;
def warn_bitfield_too_small_for_enum : Warning<
"bit-field %0 is not wide enough to store all enumerators of %1">,
InGroup<BitFieldEnumConversion>, DefaultIgnore;
def note_widen_bitfield : Note<
"widen this field to %0 bits to store all values of %1">;
def warn_unsigned_bitfield_assigned_signed_enum : Warning<
"assigning value of signed enum type %1 to unsigned bit-field %0; "
"negative enumerators of enum %1 will be converted to positive values">,
InGroup<BitFieldEnumConversion>, DefaultIgnore;
def warn_signed_bitfield_enum_conversion : Warning<
"signed bit-field %0 needs an extra bit to represent the largest positive "
"enumerators of %1">,
InGroup<BitFieldEnumConversion>, DefaultIgnore;
def note_change_bitfield_sign : Note<
"consider making the bitfield type %select{unsigned|signed}0">;
def warn_missing_braces : Warning<
"suggest braces around initialization of subobject">,
@ -5164,7 +5283,7 @@ def err_arc_inconsistent_property_ownership : Error<
def warn_block_capture_autoreleasing : Warning<
"block captures an autoreleasing out-parameter, which may result in "
"use-after-free bugs">,
InGroup<BlockCaptureAutoReleasing>, DefaultIgnore;
InGroup<BlockCaptureAutoReleasing>;
def note_declare_parameter_autoreleasing : Note<
"declare the parameter __autoreleasing explicitly to suppress this warning">;
def note_declare_parameter_strong : Note<
@ -5725,8 +5844,8 @@ def err_this_static_member_func : Error<
def err_invalid_member_use_in_static_method : Error<
"invalid use of member %0 in static member function">;
def err_invalid_qualified_function_type : Error<
"%select{static |non-}0member function %select{of type %2 |}1"
"cannot have '%3' qualifier">;
"%select{non-member function|static member function|deduction guide}0 "
"%select{of type %2 |}1cannot have '%3' qualifier">;
def err_compound_qualified_function_type : Error<
"%select{block pointer|pointer|reference}0 to function type %select{%2 |}1"
"cannot have '%3' qualifier">;
@ -5750,8 +5869,8 @@ def err_builtin_func_cast_more_than_one_arg : Error<
"function-style cast to a builtin type can only take one argument">;
def err_value_init_for_array_type : Error<
"array types cannot be value-initialized">;
def err_value_init_for_function_type : Error<
"function types cannot be value-initialized">;
def err_init_for_function_type : Error<
"cannot create object of function type %0">;
def warn_format_nonliteral_noargs : Warning<
"format string is not a string literal (potentially insecure)">,
InGroup<FormatSecurity>;
@ -5916,6 +6035,12 @@ def warn_objc_circular_container : Warning<
"adding '%0' to '%1' might cause circular dependency in container">,
InGroup<DiagGroup<"objc-circular-container">>;
def note_objc_circular_container_declared_here : Note<"'%0' declared here">;
def warn_objc_unsafe_perform_selector : Warning<
"%0 is incompatible with selectors that return a "
"%select{struct|union|vector}1 type">,
InGroup<DiagGroup<"objc-unsafe-perform-selector">>;
def note_objc_unsafe_perform_selector_method_declared_here : Note<
"method %0 that returns %1 declared here">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
@ -7001,7 +7126,7 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
def err_require_constant_init_failed : Error<
"variable does not have a constant initializer">;
def note_declared_required_constant_init_here : Note<
"required by 'require_constant_initializer' attribute here">;
"required by 'require_constant_initialization' attribute here">;
def err_dimension_expr_not_constant_integer : Error<
"dimension expression does not evaluate to a constant unsigned int">;
@ -7899,6 +8024,8 @@ def err_x86_builtin_32_bit_tgt : Error<
"this builtin is only available on x86-64 targets">;
def err_x86_builtin_invalid_rounding : Error<
"invalid rounding argument">;
def err_x86_builtin_invalid_scale : Error<
"scale argument must be 1, 2, 4, or 8">;
def err_builtin_longjmp_unsupported : Error<
"__builtin_longjmp is not supported for the current target">;
@ -8113,6 +8240,8 @@ def err_opencl_ptrptr_kernel_param : Error<
def err_kernel_arg_address_space : Error<
"pointer arguments to kernel functions must reside in '__global', "
"'__constant' or '__local' address space">;
def err_opencl_ext_vector_component_invalid_length : Error<
"vector component access has invalid length %0. Supported: 1,2,3,4,8,16.">;
def err_opencl_function_variable : Error<
"%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">;
def err_static_function_scope : Error<
@ -8158,9 +8287,9 @@ def err_opencl_return_value_with_address_space : Error<
"return value cannot be qualified with address space">;
def err_opencl_constant_no_init : Error<
"variable in constant address space must be initialized">;
def err_atomic_init_constant : Error<
"atomic variable can only be assigned to a compile time constant"
" in the declaration statement in the program scope">;
def err_opencl_atomic_init: Error<
"atomic variable can be %select{assigned|initialized}0 to a variable only "
"in global address space">;
def err_opencl_implicit_vector_conversion : Error<
"implicit conversions between vector types (%0 and %1) are not permitted">;
def err_opencl_invalid_type_array : Error<
@ -8210,6 +8339,8 @@ def err_opencl_invalid_block_declaration : Error<
"invalid block variable declaration - must be %select{const qualified|initialized}0">;
def err_opencl_extern_block_declaration : Error<
"invalid block variable declaration - using 'extern' storage class is disallowed">;
def err_opencl_block_ref_block : Error<
"cannot refer to a block inside block">;
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
def err_opencl_builtin_to_addr_arg_num : Error<
@ -8227,9 +8358,9 @@ def err_opencl_enqueue_kernel_local_size_args : Error<
def err_opencl_enqueue_kernel_invalid_local_size_type : Error<
"illegal call to enqueue_kernel, parameter needs to be specified as integer type">;
def err_opencl_enqueue_kernel_blocks_non_local_void_args : Error<
"blocks used in device side enqueue are expected to have parameters of type 'local void*'">;
"blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'">;
def err_opencl_enqueue_kernel_blocks_no_args : Error<
"blocks in this form of device side enqueue call are expected to have have no parameters">;
"blocks with parameters are not accepted in this prototype of enqueue_kernel call">;
// OpenCL v2.2 s2.1.2.3 - Vector Component Access
def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
@ -8708,8 +8839,7 @@ let CategoryName = "Coroutines Issue" in {
def err_return_in_coroutine : Error<
"return statement not allowed in coroutine; did you mean 'co_return'?">;
def note_declared_coroutine_here : Note<
"function is a coroutine due to use of "
"'%select{co_await|co_yield|co_return}0' here">;
"function is a coroutine due to use of '%0' here">;
def err_coroutine_objc_method : Error<
"Objective-C methods as coroutines are not yet supported">;
def err_coroutine_unevaluated_context : Error<
@ -8721,24 +8851,38 @@ def err_coroutine_invalid_func_context : Error<
"|a copy assignment operator|a move assignment operator|the 'main' function"
"|a constexpr function|a function with a deduced return type"
"|a varargs function}0">;
def err_implied_std_coroutine_traits_not_found : Error<
"you need to include <experimental/coroutine> before defining a coroutine">;
def err_implied_coroutine_type_not_found : Error<
"%0 type was not found; include <experimental/coroutine> before defining "
"a coroutine">;
def err_malformed_std_coroutine_handle : Error<
"std::experimental::coroutine_handle must be a class template">;
def err_coroutine_handle_missing_member : Error<
"std::experimental::coroutine_handle missing a member named '%0'">;
def err_malformed_std_coroutine_traits : Error<
"'std::experimental::coroutine_traits' must be a class template">;
def err_implied_std_coroutine_traits_promise_type_not_found : Error<
"this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
def err_implied_std_coroutine_traits_promise_type_not_class : Error<
"this function cannot be a coroutine: %0 is not a class">;
def err_coroutine_traits_missing_specialization : Error<
def err_coroutine_promise_type_incomplete : Error<
"this function cannot be a coroutine: %0 is an incomplete type">;
def err_coroutine_type_missing_specialization : Error<
"this function cannot be a coroutine: missing definition of "
"specialization %q0">;
def err_implied_std_current_exception_not_found : Error<
"you need to include <exception> before defining a coroutine that implicitly "
"uses 'set_exception'">;
def err_malformed_std_current_exception : Error<
"'std::current_exception' must be a function">;
def err_coroutine_promise_return_ill_formed : Error<
"%0 declares both 'return_value' and 'return_void'">;
def note_coroutine_promise_implicit_await_transform_required_here : Note<
"call to 'await_transform' implicitly required by 'co_await' here">;
def note_coroutine_promise_call_implicitly_required : Note<
"call to '%select{initial_suspend|final_suspend}0' implicitly "
"required by the %select{initial suspend point|final suspend point}0">;
def err_coroutine_promise_unhandled_exception_required : Error<
"%0 is required to declare the member 'unhandled_exception()'">;
def warn_coroutine_promise_unhandled_exception_required_with_exceptions : Warning<
"%0 is required to declare the member 'unhandled_exception()' when exceptions are enabled">,
InGroup<Coroutine>;
def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
"%0: 'get_return_object_on_allocation_failure()' must be a static member function">;
}
let CategoryName = "Documentation Issue" in {
@ -8905,4 +9049,9 @@ def ext_warn_gnu_final : ExtWarn<
"__final is a GNU extension, consider using C++11 final">,
InGroup<GccCompat>;
def warn_shadow_field :
Warning<"non-static data member '%0' of '%1' shadows member inherited from type '%2'">,
InGroup<ShadowField>, DefaultIgnore;
def note_shadow_field : Note<"declared here">;
} // end of sema component.

View File

@ -117,6 +117,57 @@ def note_module_odr_violation_different_definitions : Note<
def err_module_odr_violation_different_instantiations : Error<
"instantiation of %q0 is different in different modules">;
def err_module_odr_violation_mismatch_decl : Error<
"%q0 has different definitions in different modules; first difference is "
"%select{definition in module '%2'|defined here}1 found "
"%select{end of class|public access specifier|private access specifier|"
"protected access specifier|static assert|field|method}3">;
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
"%select{end of class|public access specifier|private access specifier|"
"protected access specifier|static assert|field|method}1">;
def err_module_odr_violation_mismatch_decl_diff : Error<
"%q0 has different definitions in different modules; first difference is "
"%select{definition in module '%2'|defined here}1 found "
"%select{"
"static assert with condition|"
"static assert with message|"
"static assert with %select{|no }4message|"
"field %4|"
"field %4 with type %5|"
"%select{non-|}5bitfield %4|"
"bitfield %4 with one width expression|"
"%select{non-|}5mutable field %4|"
"field %4 with %select{no|an}5 initalizer|"
"field %4 with an initializer|"
"method %4|"
"method %4 is %select{not deleted|deleted}5|"
"method %4 is %select{|pure }5%select{not virtual|virtual}6|"
"method %4 is %select{not static|static}5|"
"method %4 is %select{not volatile|volatile}5|"
"method %4 is %select{not const|const}5|"
"method %4 is %select{not inline|inline}5}3">;
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"%select{"
"static assert with different condition|"
"static assert with different message|"
"static assert with %select{|no }2message|"
"field %2|"
"field %2 with type %3|"
"%select{non-|}3bitfield %2|"
"bitfield %2 with different width expression|"
"%select{non-|}3mutable field %2|"
"field %2 with %select{no|an}3 initializer|"
"field %2 with a different initializer|"
"method %2|"
"method %2 is %select{not deleted|deleted}3|"
"method %2 is %select{|pure }3%select{not virtual|virtual}4|"
"method %2 is %select{not static|static}3|"
"method %2 is %select{not volatile|volatile}3|"
"method %2 is %select{not const|const}3|"
"method %2 is %select{not inline|inline}3}1">;
def warn_module_uses_date_time : Warning<
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
InGroup<DiagGroup<"pch-date-time">>;
@ -125,6 +176,11 @@ def warn_duplicate_module_file_extension : Warning<
"duplicate module file extension block name '%0'">,
InGroup<ModuleFileExtension>;
def warn_module_system_bit_conflict : Warning<
"module file '%0' was validated as a system module and is now being imported "
"as a non-system module; any difference in diagnostic options will be ignored">,
InGroup<ModuleConflict>;
} // let CategoryName
} // let Component

View File

@ -280,7 +280,11 @@ class IdentifierInfo {
bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
/// \brief Return true if this token is a keyword in the specified language.
bool isKeyword(const LangOptions &LangOpts);
bool isKeyword(const LangOptions &LangOpts) const;
/// \brief Return true if this token is a C++ keyword in the specified
/// language.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
/// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
/// associate arbitrary metadata with this token.
@ -818,6 +822,7 @@ class DeclarationNameExtra {
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
CXXOperator##Name,
#include "clang/Basic/OperatorKinds.def"
CXXDeductionGuide,
CXXLiteralOperator,
CXXUsingDirective,
NUM_EXTRA_KINDS

View File

@ -107,7 +107,7 @@ LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword")
BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions")
LANGOPT(GNUMode , 1, 1, "GNU extensions")
LANGOPT(GNUKeywords , 1, 1, "GNU keywords")
BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'")
LANGOPT(Digraphs , 1, 0, "digraphs")
@ -201,6 +201,8 @@ LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
BENIGN_LANGOPT(ModulesCodegen , 1, 0, "Modules code generation")
BENIGN_LANGOPT(ModulesDebugInfo , 1, 0, "Modules debug info")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
@ -215,7 +217,8 @@ BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and su
BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT")
/// \brief FP_CONTRACT mode (on/off/fast).
ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
@ -261,6 +264,8 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
"field padding (0: none, 1:least "
"aggressive, 2: more aggressive)")
LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT

View File

@ -88,6 +88,12 @@ class LangOptions : public LangOptionsBase {
MSVC2015 = 19
};
enum FPContractModeKind {
FPC_Off, // Form fused FP ops only where result will not be affected.
FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
};
public:
/// \brief Set of enabled sanitizers.
SanitizerSet Sanitize;
@ -96,6 +102,16 @@ class LangOptions : public LangOptionsBase {
/// (files, functions, variables) should not be instrumented.
std::vector<std::string> SanitizerBlacklistFiles;
/// \brief Paths to the XRay "always instrument" files specifying which
/// objects (files, functions, variables) should be imbued with the XRay
/// "always instrument" attribute.
std::vector<std::string> XRayAlwaysInstrumentFiles;
/// \brief Paths to the XRay "never instrument" files specifying which
/// objects (files, functions, variables) should be imbued with the XRay
/// "never instrument" attribute.
std::vector<std::string> XRayNeverInstrumentFiles;
clang::ObjCRuntime ObjCRuntime;
std::string ObjCConstantStringClass;
@ -170,17 +186,45 @@ class LangOptions : public LangOptionsBase {
/// \brief Is this a libc/libm function that is no longer recognized as a
/// builtin because a -fno-builtin-* option has been specified?
bool isNoBuiltinFunc(StringRef Name) const;
/// \brief True if any ObjC types may have non-trivial lifetime qualifiers.
bool allowsNonTrivialObjCLifetimeQualifiers() const {
return ObjCAutoRefCount || ObjCWeak;
}
};
/// \brief Floating point control options
class FPOptions {
public:
unsigned fp_contract : 1;
FPOptions() : fp_contract(LangOptions::FPC_Off) {}
FPOptions() : fp_contract(0) {}
// Used for serializing.
explicit FPOptions(unsigned I)
: fp_contract(static_cast<LangOptions::FPContractModeKind>(I)) {}
FPOptions(const LangOptions &LangOpts) :
fp_contract(LangOpts.DefaultFPContract) {}
explicit FPOptions(const LangOptions &LangOpts)
: fp_contract(LangOpts.getDefaultFPContractMode()) {}
bool allowFPContractWithinStatement() const {
return fp_contract == LangOptions::FPC_On;
}
bool allowFPContractAcrossStatement() const {
return fp_contract == LangOptions::FPC_Fast;
}
void setAllowFPContractWithinStatement() {
fp_contract = LangOptions::FPC_On;
}
void setAllowFPContractAcrossStatement() {
fp_contract = LangOptions::FPC_Fast;
}
void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
/// Used to serialize this.
unsigned getInt() const { return fp_contract; }
private:
/// Adjust BinaryOperator::FPFeatures to match the bit-field size of this.
unsigned fp_contract : 2;
};
/// \brief Describes the kind of translation unit being processed.

View File

@ -0,0 +1,80 @@
//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
#define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
#include <memory>
namespace llvm {
class MemoryBuffer;
} // end namespace llvm
namespace clang {
/// Manage memory buffers across multiple users.
///
/// Ensures that multiple users have a consistent view of each buffer. This is
/// used by \a CompilerInstance when building PCMs to ensure that each \a
/// ModuleManager sees the same files.
///
/// \a finalizeCurrentBuffers() should be called before creating a new user.
/// This locks in the current buffers, ensuring that no buffer that has already
/// been accessed can be purged, preventing use-after-frees.
class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
struct BufferEntry {
std::unique_ptr<llvm::MemoryBuffer> Buffer;
/// Track the timeline of when this was added to the cache.
unsigned Index;
};
/// Cache of buffers.
llvm::StringMap<BufferEntry> Buffers;
/// Monotonically increasing index.
unsigned NextIndex = 0;
/// Bumped to prevent "older" buffers from being removed.
unsigned FirstRemovableIndex = 0;
public:
/// Store the Buffer under the Filename.
///
/// \pre There is not already buffer is not already in the cache.
/// \return a reference to the buffer as a convenience.
llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,
std::unique_ptr<llvm::MemoryBuffer> Buffer);
/// Try to remove a buffer from the cache.
///
/// \return false on success, iff \c !isBufferFinal().
bool tryToRemoveBuffer(llvm::StringRef Filename);
/// Get a pointer to the buffer if it exists; else nullptr.
llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);
/// Check whether the buffer is final.
///
/// \return true iff \a finalizeCurrentBuffers() has been called since the
/// buffer was added. This prevents buffers from being removed.
bool isBufferFinal(llvm::StringRef Filename);
/// Finalize the current buffers in the cache.
///
/// Should be called when creating a new user to ensure previous uses aren't
/// invalidated.
void finalizeCurrentBuffers();
};
} // end namespace clang
#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H

View File

@ -42,7 +42,17 @@ class IdentifierInfo;
/// \brief Describes the name of a module.
typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
/// The signature of a module, which is a hash of the AST content.
struct ASTFileSignature : std::array<uint32_t, 5> {
ASTFileSignature(std::array<uint32_t, 5> S = {{0}})
: std::array<uint32_t, 5>(std::move(S)) {}
explicit operator bool() const {
return *this != std::array<uint32_t, 5>({{0}});
}
};
/// \brief Describes a module or submodule.
class Module {
public:
@ -65,7 +75,7 @@ class Module {
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
/// \brief The module signature.
uint64_t Signature;
ASTFileSignature Signature;
/// \brief The name of the umbrella entry, as written in the module map.
std::string UmbrellaAsWritten;

View File

@ -326,6 +326,20 @@ class ObjCRuntime {
}
}
/// Are the empty collection symbols available?
bool hasEmptyCollections() const {
switch (getKind()) {
default:
return false;
case MacOSX:
return getVersion() >= VersionTuple(10, 11);
case iOS:
return getVersion() >= VersionTuple(9);
case WatchOS:
return getVersion() >= VersionTuple(2);
}
}
/// \brief Try to parse an Objective-C runtime specification from the given
/// string.
///

View File

@ -66,7 +66,7 @@ IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image3d, OCLImage3d, "")
IMAGE_WRITE_TYPE(image3d, OCLImage3d, "cl_khr_3d_image_writes")
IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d, "")
IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray, "")

View File

@ -234,6 +234,11 @@ bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind);
/// directives that need loop bound sharing across loops outlined in nested
/// functions
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind);
/// Return the captured regions of an OpenMP directive.
void getOpenMPCaptureRegions(
llvm::SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
OpenMPDirectiveKind DKind);
}
#endif

View File

@ -64,6 +64,11 @@ SANITIZER("function", Function)
SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
SANITIZER("nonnull-attribute", NonnullAttribute)
SANITIZER("null", Null)
SANITIZER("nullability-arg", NullabilityArg)
SANITIZER("nullability-assign", NullabilityAssign)
SANITIZER("nullability-return", NullabilityReturn)
SANITIZER_GROUP("nullability", Nullability,
NullabilityArg | NullabilityAssign | NullabilityReturn)
SANITIZER("object-size", ObjectSize)
SANITIZER("return", Return)
SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)

View File

@ -321,8 +321,7 @@ class FullSourceLoc : public SourceLocation {
}
/// \brief Comparison function class, useful for sorting FullSourceLocs.
struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
FullSourceLoc, bool> {
struct BeforeThanCompare {
bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
return lhs.isBeforeInTranslationUnitThan(rhs);
}

View File

@ -82,11 +82,12 @@ namespace clang {
/// \brief Structure that packs information about the type specifiers that
/// were written in a particular type specifier sequence.
struct WrittenBuiltinSpecs {
/*DeclSpec::TST*/ unsigned Type : 5;
static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST");
/*DeclSpec::TST*/ unsigned Type : 6;
/*DeclSpec::TSS*/ unsigned Sign : 2;
/*DeclSpec::TSW*/ unsigned Width : 2;
unsigned ModeAttr : 1;
};
};
/// \brief A C++ access specifier (public, private, protected), plus the
/// special value "none" which means different things in different contexts.

View File

@ -43,7 +43,7 @@ def ObjCAtSynchronizedStmt : Stmt;
def ObjCForCollectionStmt : Stmt;
def ObjCAutoreleasePoolStmt : Stmt;
// C++ statments
// C++ statements
def CXXCatchStmt : Stmt;
def CXXTryStmt : Stmt;
def CXXForRangeStmt : Stmt;
@ -150,6 +150,7 @@ def CXXFoldExpr : DStmt<Expr>;
// C++ Coroutines TS expressions
def CoroutineSuspendExpr : DStmt<Expr, 1>;
def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
def DependentCoawaitExpr : DStmt<Expr>;
def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
// Obj-C Expressions.

View File

@ -154,7 +154,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
/// typedef void* __builtin_va_list;
VoidPtrBuiltinVaList,
/// __builtin_va_list as defind by the AArch64 ABI
/// __builtin_va_list as defined by the AArch64 ABI
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
AArch64ABIBuiltinVaList,
@ -168,7 +168,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
PowerABIBuiltinVaList,
/// __builtin_va_list as defined by the x86-64 ABI:
/// http://www.x86-64.org/documentation/abi.pdf
/// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf
X86_64ABIBuiltinVaList,
/// __builtin_va_list as defined by ARM AAPCS ABI
@ -823,8 +823,9 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
/// \brief Set forced language options.
///
/// Apply changes to the target information with respect to certain
/// language options which change the target configuration.
virtual void adjust(const LangOptions &Opts);
/// language options which change the target configuration and adjust
/// the language based on the target options where applicable.
virtual void adjust(LangOptions &Opts);
/// \brief Adjust target options based on codegen options.
virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
@ -1032,6 +1033,21 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
return LangAS::opencl_global;
}
/// \returns Target specific vtbl ptr address space.
virtual unsigned getVtblPtrAddressSpace() const {
return 0;
}
/// \returns If a target requires an address within a target specific address
/// space \p AddressSpace to be converted in order to be used, then return the
/// corresponding target specific DWARF address space.
///
/// \returns Otherwise return None and no conversion will be emitted in the
/// DWARF.
virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
return None;
}
/// \brief Check the target is valid after it is fully initialized.
virtual bool validateTarget(DiagnosticsEngine &Diags) const {
return true;

View File

@ -432,6 +432,7 @@ TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)
TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX)
TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX)
TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX)
TYPE_TRAIT_1(__is_aggregate, IsAggregate, KEYCXX)
TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX)
TYPE_TRAIT_1(__is_class, IsClass, KEYCXX)
TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
@ -787,6 +788,8 @@ ANNOTATION(pragma_openmp_end)
// handles #pragma loop ... directives.
ANNOTATION(pragma_loop_hint)
ANNOTATION(pragma_fp)
// Annotations for module import translated from #include etc.
ANNOTATION(module_include)
ANNOTATION(module_begin)

View File

@ -31,6 +31,7 @@ namespace clang {
UTT_HasTrivialDestructor,
UTT_HasVirtualDestructor,
UTT_IsAbstract,
UTT_IsAggregate,
UTT_IsArithmetic,
UTT_IsArray,
UTT_IsClass,

View File

@ -161,7 +161,7 @@ class directory_iterator {
directory_iterator &increment(std::error_code &EC) {
assert(Impl && "attempting to increment past end");
EC = Impl->increment();
if (EC || !Impl->CurrentEntry.isStatusKnown())
if (!Impl->CurrentEntry.isStatusKnown())
Impl.reset(); // Normalize the end iterator to Impl == nullptr.
return *this;
}

View File

@ -0,0 +1,54 @@
//===--- XRayLists.h - XRay automatic attribution ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// User-provided filters for always/never XRay instrumenting certain functions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_XRAYLISTS_H
#define LLVM_CLANG_BASIC_XRAYLISTS_H
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SpecialCaseList.h"
#include <memory>
namespace clang {
class XRayFunctionFilter {
std::unique_ptr<llvm::SpecialCaseList> AlwaysInstrument;
std::unique_ptr<llvm::SpecialCaseList> NeverInstrument;
SourceManager &SM;
public:
XRayFunctionFilter(ArrayRef<std::string> AlwaysInstrumentPaths,
ArrayRef<std::string> NeverInstrumentPaths,
SourceManager &SM);
enum class ImbueAttribute {
NONE,
ALWAYS,
NEVER,
};
ImbueAttribute shouldImbueFunction(StringRef FunctionName) const;
ImbueAttribute
shouldImbueFunctionsInFile(StringRef Filename,
StringRef Category = StringRef()) const;
ImbueAttribute shouldImbueLocation(SourceLocation Loc,
StringRef Category = StringRef()) const;
};
} // namespace clang
#endif

View File

@ -1362,7 +1362,7 @@ def SCALAR_SHL: SInst<"vshl", "sss", "SlSUl">;
def SCALAR_QSHL: SInst<"vqshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
// Scalar Saturating Rounding Shift Left
def SCALAR_QRSHL: SInst<"vqrshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
// Scalar Shift Rouding Left
// Scalar Shift Rounding Left
def SCALAR_RSHL: SInst<"vrshl", "sss", "SlSUl">;
////////////////////////////////////////////////////////////////////////////////

View File

@ -15,6 +15,8 @@
#include <memory>
namespace llvm {
class BitcodeModule;
template <typename T> class Expected;
class Module;
class MemoryBufferRef;
}
@ -44,6 +46,9 @@ namespace clang {
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
llvm::MemoryBufferRef Buf);
llvm::Expected<llvm::BitcodeModule>
FindThinLTOModule(llvm::MemoryBufferRef MBRef);
}
#endif

View File

@ -16,7 +16,7 @@
//
// It allows other clients, like LLDB, to determine the LLVM types that are
// actually used in function calls, which makes it possible to then determine
// the acutal ABI locations (e.g. registers, stack locations, etc.) that
// the actual ABI locations (e.g. registers, stack locations, etc.) that
// these parameters are stored in.
//
//===----------------------------------------------------------------------===//

View File

@ -23,14 +23,36 @@ class BackendConsumer;
class CodeGenAction : public ASTFrontendAction {
private:
// Let BackendConsumer access LinkModule.
friend class BackendConsumer;
/// Info about module to link into a module we're generating.
struct LinkModule {
/// The module to link in.
std::unique_ptr<llvm::Module> Module;
/// If true, we set attributes on Module's functions according to our
/// CodeGenOptions and LangOptions, as though we were generating the
/// function ourselves.
bool PropagateAttrs;
/// If true, we use LLVM module internalizer.
bool Internalize;
/// Bitwise combination of llvm::LinkerFlags used when we link the module.
unsigned LinkFlags;
};
unsigned Act;
std::unique_ptr<llvm::Module> TheModule;
// Vector of {Linker::Flags, Module*} pairs to specify bitcode
// modules to link in using corresponding linker flags.
SmallVector<std::pair<unsigned, llvm::Module *>, 4> LinkModules;
/// Bitcode modules to link in to our module.
SmallVector<LinkModule, 4> LinkModules;
llvm::LLVMContext *VMContext;
bool OwnsVMContext;
std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
protected:
/// Create a new code generation action. If the optional \p _VMContext
/// parameter is supplied, the action uses it without taking ownership,
@ -49,13 +71,6 @@ class CodeGenAction : public ASTFrontendAction {
public:
~CodeGenAction() override;
/// setLinkModule - Set the link module to be used by this action. If a link
/// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty,
/// the action will load it from the specified file.
void addLinkModule(llvm::Module *Mod, unsigned LinkFlags) {
LinkModules.push_back(std::make_pair(LinkFlags, Mod));
}
/// Take the generated LLVM module, for use after the action has been run.
/// The result may be null on failure.
std::unique_ptr<llvm::Module> takeModule();

Some files were not shown because too many files have changed in this diff Show More