Vendor import of clang release_40 branch r292009:

https://llvm.org/svn/llvm-project/cfe/branches/release_40@292009
This commit is contained in:
Dimitry Andric 2017-01-14 15:38:35 +00:00
parent fdc82ccb3f
commit d2e0a8dd94
224 changed files with 12945 additions and 824 deletions

View File

@ -16,7 +16,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
"--libdir"
"--includedir"
"--prefix"
"--src-root")
"--src-root"
"--cmakedir")
execute_process(
COMMAND ${CONFIG_COMMAND}
RESULT_VARIABLE HAD_ERROR
@ -41,6 +42,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
list(GET CONFIG_OUTPUT 3 INCLUDE_DIR)
list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT)
list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR)
list(GET CONFIG_OUTPUT 6 LLVM_CMAKE_PATH)
if(NOT MSVC_IDE)
set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS}
@ -58,7 +60,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}
NO_DEFAULT_PATH)
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
if(EXISTS ${LLVMCONFIG_FILE})
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")

View File

@ -64,7 +64,6 @@ call is efficient.
from ctypes import *
import collections
import sys
import clang.enumerations
@ -74,33 +73,6 @@ import clang.enumerations
# this by marshalling object arguments as void**.
c_object_p = POINTER(c_void_p)
if sys.version_info[0] > 2:
# Python 3 strings are unicode, translate them to/from utf8 for C-interop
# Python 3 replaces xrange with range, we want xrange behaviour
xrange = range
class c_string_p(c_char_p):
def __init__(self, p=None):
if type(p) == str:
p = p.encode("utf8")
super(c_char_p, self).__init__(p)
def __str__(self):
return str(self.value)
@property
def value(self):
if super(c_char_p, self).value is None:
return None
return super(c_char_p, self).value.decode("utf8")
@classmethod
def from_param(cls, param):
return cls(param)
else:
c_string_p = c_char_p
callbacks = {}
### Exception Classes ###
@ -175,7 +147,7 @@ class CachedProperty(object):
class _CXString(Structure):
"""Helper for transforming CXString results."""
_fields_ = [("spelling", c_string_p), ("free", c_int)]
_fields_ = [("spelling", c_char_p), ("free", c_int)]
def __del__(self):
conf.lib.clang_disposeString(self)
@ -357,7 +329,7 @@ class Diagnostic(object):
@property
def spelling(self):
return str(conf.lib.clang_getDiagnosticSpelling(self))
return conf.lib.clang_getDiagnosticSpelling(self)
@property
def ranges(self):
@ -386,8 +358,8 @@ class Diagnostic(object):
def __getitem__(self, key):
range = SourceRange()
value = str(conf.lib.clang_getDiagnosticFixIt(self.diag, key,
byref(range)))
value = conf.lib.clang_getDiagnosticFixIt(self.diag, key,
byref(range))
if len(value) == 0:
raise IndexError
@ -420,12 +392,12 @@ class Diagnostic(object):
@property
def category_name(self):
"""The string name of the category for this diagnostic."""
return str(conf.lib.clang_getDiagnosticCategoryText(self))
return conf.lib.clang_getDiagnosticCategoryText(self)
@property
def option(self):
"""The command-line option that enables this diagnostic."""
return str(conf.lib.clang_getDiagnosticOption(self, None))
return conf.lib.clang_getDiagnosticOption(self, None)
@property
def disable_option(self):
@ -433,7 +405,7 @@ class Diagnostic(object):
disable = _CXString()
conf.lib.clang_getDiagnosticOption(self, byref(disable))
return str(conf.lib.clang_getCString(disable))
return conf.lib.clang_getCString(disable)
def format(self, options=None):
"""
@ -582,8 +554,8 @@ class BaseEnumeration(object):
if value >= len(self.__class__._kinds):
self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1)
if self.__class__._kinds[value] is not None:
raise ValueError('{0} value {1} already loaded'.format(
str(self.__class__), value))
raise ValueError,'{0} value {1} already loaded'.format(
str(self.__class__), value)
self.value = value
self.__class__._kinds[value] = self
self.__class__._name_map = None
@ -600,12 +572,12 @@ class BaseEnumeration(object):
for key, value in self.__class__.__dict__.items():
if isinstance(value, self.__class__):
self._name_map[value] = key
return str(self._name_map[self])
return self._name_map[self]
@classmethod
def from_id(cls, id):
if id >= len(cls._kinds) or cls._kinds[id] is None:
raise ValueError('Unknown template argument kind %d' % id)
raise ValueError,'Unknown template argument kind %d' % id
return cls._kinds[id]
def __repr__(self):
@ -624,7 +596,7 @@ class CursorKind(BaseEnumeration):
@staticmethod
def get_all_kinds():
"""Return all CursorKind enumeration instances."""
return [x for x in CursorKind._kinds if x]
return filter(None, CursorKind._kinds)
def is_declaration(self):
"""Test if this is a declaration kind."""
@ -1457,9 +1429,9 @@ class Cursor(Structure):
def spelling(self):
"""Return the spelling of the entity pointed at by the cursor."""
if not hasattr(self, '_spelling'):
self._spelling = str(conf.lib.clang_getCursorSpelling(self))
self._spelling = conf.lib.clang_getCursorSpelling(self)
return str(self._spelling)
return self._spelling
@property
def displayname(self):
@ -1471,7 +1443,7 @@ class Cursor(Structure):
arguments of a class template specialization.
"""
if not hasattr(self, '_displayname'):
self._displayname = str(conf.lib.clang_getCursorDisplayName(self))
self._displayname = conf.lib.clang_getCursorDisplayName(self)
return self._displayname
@ -1479,7 +1451,7 @@ class Cursor(Structure):
def mangled_name(self):
"""Return the mangled name for the entity referenced by this cursor."""
if not hasattr(self, '_mangled_name'):
self._mangled_name = str(conf.lib.clang_Cursor_getMangling(self))
self._mangled_name = conf.lib.clang_Cursor_getMangling(self)
return self._mangled_name
@ -1618,7 +1590,7 @@ class Cursor(Structure):
self._objc_type_encoding = \
conf.lib.clang_getDeclObjCTypeEncoding(self)
return str(self._objc_type_encoding)
return self._objc_type_encoding
@property
def hash(self):
@ -1665,23 +1637,17 @@ class Cursor(Structure):
@property
def brief_comment(self):
"""Returns the brief comment text associated with that Cursor"""
r = conf.lib.clang_Cursor_getBriefCommentText(self)
if not r:
return None
return str(r)
return conf.lib.clang_Cursor_getBriefCommentText(self)
@property
def raw_comment(self):
"""Returns the raw comment text associated with that Cursor"""
r = conf.lib.clang_Cursor_getRawCommentText(self)
if not r:
return None
return str(r)
return conf.lib.clang_Cursor_getRawCommentText(self)
def get_arguments(self):
"""Return an iterator for accessing the arguments of this cursor."""
num_args = conf.lib.clang_Cursor_getNumArguments(self)
for i in xrange(0, num_args):
for i in range(0, num_args):
yield conf.lib.clang_Cursor_getArgument(self, i)
def get_num_template_arguments(self):
@ -1811,7 +1777,7 @@ class StorageClass(object):
if value >= len(StorageClass._kinds):
StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1)
if StorageClass._kinds[value] is not None:
raise ValueError('StorageClass already loaded')
raise ValueError,'StorageClass already loaded'
self.value = value
StorageClass._kinds[value] = self
StorageClass._name_map = None
@ -1832,7 +1798,7 @@ class StorageClass(object):
@staticmethod
def from_id(id):
if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
raise ValueError('Unknown storage class %d' % id)
raise ValueError,'Unknown storage class %d' % id
return StorageClass._kinds[id]
def __repr__(self):
@ -1885,7 +1851,7 @@ class TypeKind(BaseEnumeration):
@property
def spelling(self):
"""Retrieve the spelling of this TypeKind."""
return str(conf.lib.clang_getTypeKindSpelling(self.value))
return conf.lib.clang_getTypeKindSpelling(self.value)
def __repr__(self):
return 'TypeKind.%s' % (self.name,)
@ -2161,7 +2127,7 @@ class Type(Structure):
"""
Retrieve the offset of a field in the record.
"""
return conf.lib.clang_Type_getOffsetOf(self, fieldname)
return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
def get_ref_qualifier(self):
"""
@ -2188,7 +2154,7 @@ class Type(Structure):
@property
def spelling(self):
"""Retrieve the spelling of this Type."""
return str(conf.lib.clang_getTypeSpelling(self))
return conf.lib.clang_getTypeSpelling(self)
def __eq__(self, other):
if type(other) != type(self):
@ -2220,7 +2186,7 @@ class ClangObject(object):
class _CXUnsavedFile(Structure):
"""Helper for passing unsaved file arguments."""
_fields_ = [("name", c_string_p), ("contents", c_string_p), ('length', c_ulong)]
_fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
# Functions calls through the python interface are rather slow. Fortunately,
# for most symboles, we do not need to perform a function call. Their spelling
@ -2266,7 +2232,7 @@ class CompletionChunk:
self.__kindNumberCache = -1
def __repr__(self):
return "{'" + str(self.spelling) + "', " + str(self.kind) + "}"
return "{'" + self.spelling + "', " + str(self.kind) + "}"
@CachedProperty
def spelling(self):
@ -2575,9 +2541,7 @@ class TranslationUnit(ClangObject):
args_array = None
if len(args) > 0:
args_array = (c_string_p * len(args))()
for i,a in enumerate(args):
args_array[i] = c_string_p(a)
args_array = (c_char_p * len(args))(* args)
unsaved_array = None
if len(unsaved_files) > 0:
@ -2586,8 +2550,8 @@ class TranslationUnit(ClangObject):
if hasattr(contents, "read"):
contents = contents.read()
unsaved_array[i].name = c_string_p(name)
unsaved_array[i].contents = c_string_p(contents)
unsaved_array[i].name = name
unsaved_array[i].contents = contents
unsaved_array[i].length = len(contents)
ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
@ -2642,7 +2606,7 @@ class TranslationUnit(ClangObject):
@property
def spelling(self):
"""Get the original translation unit source file name."""
return str(conf.lib.clang_getTranslationUnitSpelling(self))
return conf.lib.clang_getTranslationUnitSpelling(self)
def get_includes(self):
"""
@ -2765,9 +2729,9 @@ class TranslationUnit(ClangObject):
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
print(value)
print value
if not isinstance(value, str):
raise TypeError('Unexpected unsaved file contents.')
raise TypeError,'Unexpected unsaved file contents.'
unsaved_files_array[i].name = name
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
@ -2829,11 +2793,11 @@ class TranslationUnit(ClangObject):
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
print(value)
print value
if not isinstance(value, str):
raise TypeError('Unexpected unsaved file contents.')
unsaved_files_array[i].name = c_string_p(name)
unsaved_files_array[i].contents = c_string_p(value)
raise TypeError,'Unexpected unsaved file contents.'
unsaved_files_array[i].name = name
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
ptr = conf.lib.clang_codeCompleteAt(self, path, line, column,
unsaved_files_array, len(unsaved_files), options)
@ -2868,7 +2832,7 @@ class File(ClangObject):
@property
def name(self):
"""Return the complete file and path name of the file."""
return str(conf.lib.clang_getCString(conf.lib.clang_getFileName(self)))
return conf.lib.clang_getCString(conf.lib.clang_getFileName(self))
@property
def time(self):
@ -2876,7 +2840,7 @@ class File(ClangObject):
return conf.lib.clang_getFileTime(self)
def __str__(self):
return str(self.name)
return self.name
def __repr__(self):
return "<File: %s>" % (self.name)
@ -2945,12 +2909,12 @@ class CompileCommand(object):
@property
def directory(self):
"""Get the working directory for this CompileCommand"""
return str(conf.lib.clang_CompileCommand_getDirectory(self.cmd))
return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
@property
def filename(self):
"""Get the working filename for this CompileCommand"""
return str(conf.lib.clang_CompileCommand_getFilename(self.cmd))
return conf.lib.clang_CompileCommand_getFilename(self.cmd)
@property
def arguments(self):
@ -2962,7 +2926,7 @@ class CompileCommand(object):
"""
length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
for i in xrange(length):
yield str(conf.lib.clang_CompileCommand_getArg(self.cmd, i))
yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
class CompileCommands(object):
"""
@ -3056,7 +3020,7 @@ class Token(Structure):
This is the textual representation of the token in source.
"""
return str(conf.lib.clang_getTokenSpelling(self._tu, self))
return conf.lib.clang_getTokenSpelling(self._tu, self)
@property
def kind(self):
@ -3099,7 +3063,7 @@ functionList = [
[c_object_p]),
("clang_CompilationDatabase_fromDirectory",
[c_string_p, POINTER(c_uint)],
[c_char_p, POINTER(c_uint)],
c_object_p,
CompilationDatabase.from_result),
@ -3109,7 +3073,7 @@ functionList = [
CompileCommands.from_result),
("clang_CompilationDatabase_getCompileCommands",
[c_object_p, c_string_p],
[c_object_p, c_char_p],
c_object_p,
CompileCommands.from_result),
@ -3144,7 +3108,7 @@ functionList = [
c_uint),
("clang_codeCompleteAt",
[TranslationUnit, c_string_p, c_int, c_int, c_void_p, c_int, c_int],
[TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int],
POINTER(CCRStructure)),
("clang_codeCompleteGetDiagnostic",
@ -3160,7 +3124,7 @@ functionList = [
c_object_p),
("clang_createTranslationUnit",
[Index, c_string_p],
[Index, c_char_p],
c_object_p),
("clang_CXXConstructor_isConvertingConstructor",
@ -3310,7 +3274,7 @@ functionList = [
("clang_getCString",
[_CXString],
c_string_p),
c_char_p),
("clang_getCursor",
[TranslationUnit, SourceLocation],
@ -3457,7 +3421,7 @@ functionList = [
Type.from_result),
("clang_getFile",
[TranslationUnit, c_string_p],
[TranslationUnit, c_char_p],
c_object_p),
("clang_getFileName",
@ -3586,7 +3550,7 @@ functionList = [
("clang_getTUResourceUsageName",
[c_uint],
c_string_p),
c_char_p),
("clang_getTypeDeclaration",
[Type],
@ -3681,7 +3645,7 @@ functionList = [
bool),
("clang_parseTranslationUnit",
[Index, c_string_p, c_void_p, c_int, c_void_p, c_int, c_int],
[Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int],
c_object_p),
("clang_reparseTranslationUnit",
@ -3689,7 +3653,7 @@ functionList = [
c_int),
("clang_saveTranslationUnit",
[TranslationUnit, c_string_p, c_uint],
[TranslationUnit, c_char_p, c_uint],
c_int),
("clang_tokenize",
@ -3761,7 +3725,7 @@ functionList = [
Type.from_result),
("clang_Type_getOffsetOf",
[Type, c_string_p],
[Type, c_char_p],
c_longlong),
("clang_Type_getSizeOf",
@ -3820,8 +3784,7 @@ def register_functions(lib, ignore_errors):
def register(item):
return register_function(lib, item, ignore_errors)
for f in functionList:
register(f)
map(register, functionList)
class Config:
library_path = None

View File

@ -59,13 +59,9 @@ int SOME_DEFINE;
assert spellings[-1] == 'y'
def test_unsaved_files_2():
try:
from StringIO import StringIO
except:
from io import StringIO
import StringIO
tu = TranslationUnit.from_source('fake.c', unsaved_files = [
('fake.c', StringIO('int x;'))])
('fake.c', StringIO.StringIO('int x;'))])
spellings = [c.spelling for c in tu.cursor.get_children()]
assert spellings[-1] == 'x'

File diff suppressed because it is too large Load Diff

View File

@ -31,11 +31,6 @@ 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>`_.
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 4.0.0?
==========================
@ -65,6 +60,8 @@ 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 -MJ has been added to simplify adding JSON compilation
database output into existing build systems.
The option ....

View File

@ -41,6 +41,7 @@ specific section:
variants depending on base language.
- :ref:`C++ Language <cxx>`
- :ref:`Objective C++ Language <objcxx>`
- :ref:`OpenCL C Language <opencl>`: v1.0, v1.1, v1.2, v2.0.
In addition to these base languages and their dialects, Clang supports a
broad variety of language extensions, which are documented in the
@ -1973,6 +1974,365 @@ Controlling implementation limits
is provided or target does not support TLS, code generation for threadprivate
variables relies on OpenMP runtime library.
.. _opencl:
OpenCL Features
===============
Clang can be used to compile OpenCL kernels for execution on a device
(e.g. GPU). It is possible to compile the kernel into a binary (e.g. for AMD or
Nvidia targets) that can be uploaded to run directly on a device (e.g. using
`clCreateProgramWithBinary
<https://www.khronos.org/registry/OpenCL/specs/opencl-1.1.pdf#111>`_) or
into generic bitcode files loadable into other toolchains.
Compiling to a binary using the default target from the installation can be done
as follows:
.. code-block:: console
$ echo "kernel void k(){}" > test.cl
$ clang test.cl
Compiling for a specific target can be done by specifying the triple corresponding
to the target, for example:
.. code-block:: console
$ clang -target nvptx64-unknown-unknown test.cl
$ clang -target amdgcn-amd-amdhsa-opencl test.cl
Compiling to bitcode can be done as follows:
.. code-block:: console
$ clang -c -emit-llvm test.cl
This will produce a generic test.bc file that can be used in vendor toolchains
to perform machine code generation.
Clang currently supports OpenCL C language standards up to v2.0.
OpenCL Specific Options
-----------------------
Most of the OpenCL build options from `the specification v2.0 section 5.8.4
<https://www.khronos.org/registry/cl/specs/opencl-2.0.pdf#200>`_ are available.
Examples:
.. code-block:: console
$ clang -cl-std=CL2.0 -cl-single-precision-constant test.cl
Some extra options are available to support special OpenCL features.
.. option:: -finclude-default-header
Loads standard includes during compilations. By default OpenCL headers are not
loaded and therefore standard library includes are not available. To load them
automatically a flag has been added to the frontend (see also :ref:`the section
on the OpenCL Header <opencl_header>`):
.. code-block:: console
$ clang -Xclang -finclude-default-header test.cl
Alternatively ``-include`` or ``-I`` followed by the path to the header location
can be given manually.
.. code-block:: console
$ clang -I<path to clang>/lib/Headers/opencl-c.h test.cl
In this case the kernel code should contain ``#include <opencl-c.h>`` just as a
regular C include.
.. option:: -cl-ext
Disables support of OpenCL extensions. All OpenCL targets provide a list
of extensions that they support. Clang allows to amend this using the ``-cl-ext``
flag with a comma-separated list of extensions prefixed with ``'+'`` or ``'-'``.
The syntax: ``-cl-ext=<(['-'|'+']<extension>[,])+>``, where extensions
can be either one of `the OpenCL specification extensions
<https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/EXTENSION.html>`_
or any known vendor extension. Alternatively, ``'all'`` can be used to enable
or disable all known extensions.
Example disabling double support for the 64-bit SPIR target:
.. code-block:: console
$ clang -cc1 -triple spir64-unknown-unknown -cl-ext=-cl_khr_fp64 test.cl
Enabling all extensions except double support in R600 AMD GPU can be done using:
.. code-block:: console
$ clang -cc1 -triple r600-unknown-unknown -cl-ext=-all,+cl_khr_fp16 test.cl
.. _opencl_fake_address_space_map:
.. option:: -ffake-address-space-map
Overrides the target address space map with a fake map.
This allows adding explicit address space IDs to the bitcode for non-segmented
memory architectures that don't have separate IDs for each of the OpenCL
logical address spaces by default. Passing ``-ffake-address-space-map`` will
add/override address spaces of the target compiled for with the following values:
``1-global``, ``2-constant``, ``3-local``, ``4-generic``. The private address
space is represented by the absence of an address space attribute in the IR (see
also :ref:`the section on the address space attribute <opencl_addrsp>`).
.. code-block:: console
$ clang -ffake-address-space-map test.cl
Some other flags used for the compilation for C can also be passed while
compiling for OpenCL, examples: ``-c``, ``-O<1-4|s>``, ``-o``, ``-emit-llvm``, etc.
OpenCL Targets
--------------
OpenCL targets are derived from the regular Clang target classes. The OpenCL
specific parts of the target representation provide address space mapping as
well as a set of supported extensions.
Specific Targets
^^^^^^^^^^^^^^^^
There is a set of concrete HW architectures that OpenCL can be compiled for.
- For AMD target:
.. code-block:: console
$ clang -target amdgcn-amd-amdhsa-opencl test.cl
- For Nvidia architectures:
.. code-block:: console
$ clang -target nvptx64-unknown-unknown test.cl
Generic Targets
^^^^^^^^^^^^^^^
- SPIR is available as a generic target to allow portable bitcode to be produced
that can be used across GPU toolchains. The implementation follows `the SPIR
specification <https://www.khronos.org/spir>`_. There are two flavors
available for 32 and 64 bits.
.. code-block:: console
$ clang -target spir-unknown-unknown test.cl
$ clang -target spir64-unknown-unknown test.cl
All known OpenCL extensions are supported in the SPIR targets. Clang will
generate SPIR v1.2 compatible IR for OpenCL versions up to 2.0 and SPIR v2.0
for OpenCL v2.0.
- x86 is used by some implementations that are x86 compatible and currently
remains for backwards compatibility (with older implementations prior to
SPIR target support). For "non-SPMD" targets which cannot spawn multiple
work-items on the fly using hardware, which covers practically all non-GPU
devices such as CPUs and DSPs, additional processing is needed for the kernels
to support multiple work-item execution. For this, a 3rd party toolchain,
such as for example `POCL <http://portablecl.org/>`_, can be used.
This target does not support multiple memory segments and, therefore, the fake
address space map can be added using the :ref:`-ffake-address-space-map
<opencl_fake_address_space_map>` flag.
.. _opencl_header:
OpenCL Header
-------------
By default Clang will not include standard headers and therefore OpenCL builtin
functions and some types (i.e. vectors) are unknown. The default CL header is,
however, provided in the Clang installation and can be enabled by passing the
``-finclude-default-header`` flag to the Clang frontend.
.. code-block:: console
$ echo "bool is_wg_uniform(int i){return get_enqueued_local_size(i)==get_local_size(i);}" > test.cl
$ clang -Xclang -finclude-default-header -cl-std=CL2.0 test.cl
Because the header is very large and long to parse, PCH (:doc:`PCHInternals`)
and modules (:doc:`Modules`) are used internally to improve the compilation
speed.
To enable modules for OpenCL:
.. code-block:: console
$ clang -target spir-unknown-unknown -c -emit-llvm -Xclang -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=<path to the generated module> test.cl
OpenCL Metadata
---------------
Clang uses metadata to provide additional OpenCL semantics in IR needed for
backends and OpenCL runtime.
Each kernel will have function metadata attached to it, specifying the arguments.
Kernel argument metadata is used to provide source level information for querying
at runtime, for example using the `clGetKernelArgInfo
<https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf#167>`_
call.
Note that ``-cl-kernel-arg-info`` enables more information about the original CL
code to be added e.g. kernel parameter names will appear in the OpenCL metadata
along with other information.
The IDs used to encode the OpenCL's logical address spaces in the argument info
metadata follows the SPIR address space mapping as defined in the SPIR
specification `section 2.2
<https://www.khronos.org/registry/spir/specs/spir_spec-2.0.pdf#18>`_
OpenCL-Specific Attributes
--------------------------
OpenCL support in Clang contains a set of attribute taken directly from the
specification as well as additional attributes.
See also :doc:`AttributeReference`.
nosvm
^^^^^
Clang supports this attribute to comply to OpenCL v2.0 conformance, but it
does not have any effect on the IR. For more details reffer to the specification
`section 6.7.2
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#49>`_
opencl_hint_unroll
^^^^^^^^^^^^^^^^^^
The implementation of this feature mirrors the unroll hint for C.
More details on the syntax can be found in the specification
`section 6.11.5
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#61>`_
convergent
^^^^^^^^^^
To make sure no invalid optimizations occur for single program multiple data
(SPMD) / single instruction multiple thread (SIMT) Clang provides attributes that
can be used for special functions that have cross work item semantics.
An example is the subgroup operations such as `intel_sub_group_shuffle
<https://www.khronos.org/registry/cl/extensions/intel/cl_intel_subgroups.txt>`_
.. code-block:: c
// Define custom my_sub_group_shuffle(data, c)
// that makes use of intel_sub_group_shuffle
r1 = …
if (r0) r1 = computeA();
// Shuffle data from r1 into r3
// of threads id r2.
r3 = my_sub_group_shuffle(r1, r2);
if (r0) r3 = computeB();
with non-SPMD semantics this is optimized to the following equivalent code:
.. code-block:: c
r1 = …
if (!r0)
// Incorrect functionality! The data in r1
// have not been computed by all threads yet.
r3 = my_sub_group_shuffle(r1, r2);
else {
r1 = computeA();
r3 = my_sub_group_shuffle(r1, r2);
r3 = computeB();
}
Declaring the function ``my_sub_group_shuffle`` with the convergent attribute
would prevent this:
.. code-block:: c
my_sub_group_shuffle() __attribute__((convergent));
Using ``convergent`` guarantees correct execution by keeping CFG equivalence
wrt operations marked as ``convergent``. CFG ``G´`` is equivalent to ``G`` wrt
node ``Ni`` : ``iff ∀ Nj (i≠j)`` domination and post-domination relations with
respect to ``Ni`` remain the same in both ``G`` and ``G´``.
noduplicate
^^^^^^^^^^^
``noduplicate`` is more restrictive with respect to optimizations than
``convergent`` because a convergent function only preserves CFG equivalence.
This allows some optimizations to happen as long as the control flow remains
unmodified.
.. code-block:: c
for (int i=0; i<4; i++)
my_sub_group_shuffle()
can be modified to:
.. code-block:: c
my_sub_group_shuffle();
my_sub_group_shuffle();
my_sub_group_shuffle();
my_sub_group_shuffle();
while using ``noduplicate`` would disallow this. Also ``noduplicate`` doesn't
have the same safe semantics of CFG as ``convergent`` and can cause changes in
CFG that modify semantics of the original program.
``noduplicate`` is kept for backwards compatibility only and it considered to be
deprecated for future uses.
.. _opencl_addrsp:
address_space
^^^^^^^^^^^^^
Clang has arbitrary address space support using the ``address_space(N)``
attribute, where ``N`` is an integer number in the range ``0`` to ``16777215``
(``0xffffffu``).
An OpenCL implementation provides a list of standard address spaces using
keywords: ``private``, ``local``, ``global``, and ``generic``. In the AST and
in the IR local, global, or generic will be represented by the address space
attribute with the corresponding unique number. Note that private does not have
any corresponding attribute added and, therefore, is represented by the absence
of an address space number. The specific IDs for an address space do not have to
match between the AST and the IR. Typically in the AST address space numbers
represent logical segments while in the IR they represent physical segments.
Therefore, machines with flat memory segments can map all AST address space
numbers to the same physical segment ID or skip address space attribute
completely while generating the IR. However, if the address space information
is needed by the IR passes e.g. to improve alias analysis, it is recommended
to keep it and only lower to reflect physical memory segments in the late
machine passes.
OpenCL builtins
---------------
There are some standard OpenCL functions that are implemented as Clang builtins:
- All pipe functions from `section 6.13.16.2/6.13.16.3
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#160>`_ of
the OpenCL v2.0 kernel language specification. `
- Address space qualifier conversion functions ``to_global``/``to_local``/``to_private``
from `section 6.13.9
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#101>`_.
- All the ``enqueue_kernel`` functions from `section 6.13.17.1
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#164>`_ and
enqueue query functions from `section 6.13.17.5
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#171>`_.
.. _target_features:
Target-Specific Features and Limitations
@ -2102,7 +2462,7 @@ Clang expects the GCC executable "gcc.exe" compiled for
clang-cl
========
clang-cl is an alternative command-line interface to Clang driver, designed for
clang-cl is an alternative command-line interface to Clang, designed for
compatibility with the Visual C++ compiler, cl.exe.
To enable clang-cl to find system headers, libraries, and the linker when run
@ -2110,7 +2470,7 @@ from the command-line, it should be executed inside a Visual Studio Native Tools
Command Prompt or a regular Command Prompt where the environment has been set
up using e.g. `vcvars32.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
clang-cl can also be used from inside Visual Studio by using an LLVM Platform
clang-cl can also be used from inside Visual Studio by using an LLVM Platform
Toolset.
Command-Line Options
@ -2145,116 +2505,125 @@ Execute ``clang-cl /?`` to see a list of supported options:
::
CL.EXE COMPATIBILITY OPTIONS:
/? Display available options
/arch:<value> Set architecture for code generation
/Brepro- Emit an object file which cannot be reproduced over time
/Brepro Emit an object file which can be reproduced over time
/C Don't discard comments when preprocessing
/c Compile only
/D <macro[=value]> Define macro
/EH<value> Exception handling model
/EP Disable linemarker output and preprocess to stdout
/E Preprocess to stdout
/fallback Fall back to cl.exe if clang-cl fails to compile
/FA Output assembly code file during compilation
/Fa<file or directory> Output assembly code to this file during compilation (with /FA)
/Fe<file or directory> Set output executable file or directory (ends in / or \)
/FI <value> Include file before parsing
/Fi<file> Set preprocess output file name (with /P)
/Fo<file or directory> Set output object file, or directory (ends in / or \) (with /c)
/? Display available options
/arch:<value> Set architecture for code generation
/Brepro- Emit an object file which cannot be reproduced over time
/Brepro Emit an object file which can be reproduced over time
/C Don't discard comments when preprocessing
/c Compile only
/D <macro[=value]> Define macro
/EH<value> Exception handling model
/EP Disable linemarker output and preprocess to stdout
/execution-charset:<value>
Runtime encoding, supports only UTF-8
/E Preprocess to stdout
/fallback Fall back to cl.exe if clang-cl fails to compile
/FA Output assembly code file during compilation
/Fa<file or directory> Output assembly code to this file during compilation (with /FA)
/Fe<file or directory> Set output executable file or directory (ends in / or \)
/FI <value> Include file before parsing
/Fi<file> Set preprocess output file name (with /P)
/Fo<file or directory> Set output object file, or directory (ends in / or \) (with /c)
/fp:except-
/fp:except
/fp:fast
/fp:precise
/fp:strict
/Fp<filename> Set pch filename (with /Yc and /Yu)
/GA Assume thread-local variables are defined in the executable
/Gd Set __cdecl as a default calling convention
/GF- Disable string pooling
/GR- Disable emission of RTTI data
/GR Enable emission of RTTI data
/Gr Set __fastcall as a default calling convention
/GS- Disable buffer security check
/GS Enable buffer security check
/Gs<value> Set stack probe size
/Gv Set __vectorcall as a default calling convention
/Gw- Don't put each data item in its own section
/Gw Put each data item in its own section
/GX- Enable exception handling
/GX Enable exception handling
/Gy- Don't put each function in its own section
/Gy Put each function in its own section
/Gz Set __stdcall as a default calling convention
/help Display available options
/imsvc <dir> Add directory to system include search path, as if part of %INCLUDE%
/I <dir> Add directory to include search path
/J Make char type unsigned
/LDd Create debug DLL
/LD Create DLL
/link <options> Forward options to the linker
/MDd Use DLL debug run-time
/MD Use DLL run-time
/MTd Use static debug run-time
/MT Use static run-time
/Od Disable optimization
/Oi- Disable use of builtin functions
/Oi Enable use of builtin functions
/Os Optimize for size
/Ot Optimize for speed
/O<value> Optimization level
/o <file or directory> Set output file or directory (ends in / or \)
/P Preprocess to file
/Qvec- Disable the loop vectorization passes
/Qvec Enable the loop vectorization passes
/showIncludes Print info about included files to stderr
/std:<value> Language standard to compile for
/TC Treat all source files as C
/Tc <filename> Specify a C source file
/TP Treat all source files as C++
/Tp <filename> Specify a C++ source file
/U <macro> Undefine macro
/vd<value> Control vtordisp placement
/vmb Use a best-case representation method for member pointers
/vmg Use a most-general representation for member pointers
/vmm Set the default most-general representation to multiple inheritance
/vms Set the default most-general representation to single inheritance
/vmv Set the default most-general representation to virtual inheritance
/volatile:iso Volatile loads and stores have standard semantics
/volatile:ms Volatile loads and stores have acquire and release semantics
/W0 Disable all warnings
/W1 Enable -Wall
/W2 Enable -Wall
/W3 Enable -Wall
/W4 Enable -Wall and -Wextra
/Wall Enable -Wall and -Wextra
/WX- Do not treat warnings as errors
/WX Treat warnings as errors
/w Disable all warnings
/Y- Disable precompiled headers, overrides /Yc and /Yu
/Yc<filename> Generate a pch file for all code up to and including <filename>
/Yu<filename> Load a pch file and use it instead of all code up to and including <filename>
/Z7 Enable CodeView debug information in object files
/Zc:sizedDealloc- Disable C++14 sized global deallocation functions
/Zc:sizedDealloc Enable C++14 sized global deallocation functions
/Zc:strictStrings Treat string literals as const
/Zc:threadSafeInit- Disable thread-safe initialization of static variables
/Zc:threadSafeInit Enable thread-safe initialization of static variables
/Zc:trigraphs- Disable trigraphs (default)
/Zc:trigraphs Enable trigraphs
/Zd Emit debug line number tables only
/Zi Alias for /Z7. Does not produce PDBs.
/Zl Don't mention any default libraries in the object file
/Zp Set the default maximum struct packing alignment to 1
/Zp<value> Specify the default maximum struct packing alignment
/Zs Syntax-check only
/Fp<filename> Set pch filename (with /Yc and /Yu)
/GA Assume thread-local variables are defined in the executable
/Gd Set __cdecl as a default calling convention
/GF- Disable string pooling
/GR- Disable emission of RTTI data
/GR Enable emission of RTTI data
/Gr Set __fastcall as a default calling convention
/GS- Disable buffer security check
/GS Enable buffer security check
/Gs<value> Set stack probe size
/Gv Set __vectorcall as a default calling convention
/Gw- Don't put each data item in its own section
/Gw Put each data item in its own section
/GX- Enable exception handling
/GX Enable exception handling
/Gy- Don't put each function in its own section
/Gy Put each function in its own section
/Gz Set __stdcall as a default calling convention
/help Display available options
/imsvc <dir> Add directory to system include search path, as if part of %INCLUDE%
/I <dir> Add directory to include search path
/J Make char type unsigned
/LDd Create debug DLL
/LD Create DLL
/link <options> Forward options to the linker
/MDd Use DLL debug run-time
/MD Use DLL run-time
/MTd Use static debug run-time
/MT Use static run-time
/Od Disable optimization
/Oi- Disable use of builtin functions
/Oi Enable use of builtin functions
/Os Optimize for size
/Ot Optimize for speed
/O<value> Optimization level
/o <file or directory> Set output file or directory (ends in / or \)
/P Preprocess to file
/Qvec- Disable the loop vectorization passes
/Qvec Enable the loop vectorization passes
/showIncludes Print info about included files to stderr
/source-charset:<value> Source encoding, supports only UTF-8
/std:<value> Language standard to compile for
/TC Treat all source files as C
/Tc <filename> Specify a C source file
/TP Treat all source files as C++
/Tp <filename> Specify a C++ source file
/utf-8 Set source and runtime encoding to UTF-8 (default)
/U <macro> Undefine macro
/vd<value> Control vtordisp placement
/vmb Use a best-case representation method for member pointers
/vmg Use a most-general representation for member pointers
/vmm Set the default most-general representation to multiple inheritance
/vms Set the default most-general representation to single inheritance
/vmv Set the default most-general representation to virtual inheritance
/volatile:iso Volatile loads and stores have standard semantics
/volatile:ms Volatile loads and stores have acquire and release semantics
/W0 Disable all warnings
/W1 Enable -Wall
/W2 Enable -Wall
/W3 Enable -Wall
/W4 Enable -Wall and -Wextra
/Wall Enable -Wall and -Wextra
/WX- Do not treat warnings as errors
/WX Treat warnings as errors
/w Disable all warnings
/Y- Disable precompiled headers, overrides /Yc and /Yu
/Yc<filename> Generate a pch file for all code up to and including <filename>
/Yu<filename> Load a pch file and use it instead of all code up to and including <filename>
/Z7 Enable CodeView debug information in object files
/Zc:sizedDealloc- Disable C++14 sized global deallocation functions
/Zc:sizedDealloc Enable C++14 sized global deallocation functions
/Zc:strictStrings Treat string literals as const
/Zc:threadSafeInit- Disable thread-safe initialization of static variables
/Zc:threadSafeInit Enable thread-safe initialization of static variables
/Zc:trigraphs- Disable trigraphs (default)
/Zc:trigraphs Enable trigraphs
/Zd Emit debug line number tables only
/Zi Alias for /Z7. Does not produce PDBs.
/Zl Don't mention any default libraries in the object file
/Zp Set the default maximum struct packing alignment to 1
/Zp<value> Specify the default maximum struct packing alignment
/Zs Syntax-check only
OPTIONS:
-### Print (but do not run) the commands to run for this compilation
--analyze Run the static analyzer
-fansi-escape-codes Use ANSI escape codes for diagnostics
-fcolor-diagnostics Use colors in diagnostics
-fdelayed-template-parsing
Parse templated function definitions at the end of the translation unit
-fdiagnostics-absolute-paths
Print absolute paths in diagnostics
-fdiagnostics-parseable-fixits
Print fix-its in machine parseable form
-flto Enable LTO in 'full' mode
-fms-compatibility-version=<value>
Dot-separated value representing the Microsoft compiler version
number to report in _MSC_VER (0 = don't define it (default))
@ -2262,12 +2631,23 @@ Execute ``clang-cl /?`` to see a list of supported options:
-fms-extensions Accept some non-standard constructs supported by the Microsoft compiler
-fmsc-version=<value> Microsoft compiler version number to report in _MSC_VER
(0 = don't define it (default))
-fno-delayed-template-parsing
Disable delayed template parsing
-fno-sanitize-coverage=<value>
Disable specified features of coverage instrumentation for Sanitizers
-fno-sanitize-recover=<value>
Disable recovery for specified sanitizers
-fno-sanitize-trap=<value>
Disable trapping for specified sanitizers
-fno-standalone-debug Limit debug information produced to reduce size of debug binary
-fprofile-instr-generate=<file>
Generate instrumented code to collect execution counts into <file>
(overridden by LLVM_PROFILE_FILE env var)
-fprofile-instr-generate
Generate instrumented code to collect execution counts into default.profraw file
(overriden by '=' form of option or LLVM_PROFILE_FILE env var)
-fprofile-instr-use=<value>
Use instrumentation data for profile-guided optimization
-fsanitize-blacklist=<value>
Path to blacklist file for sanitizers
-fsanitize-coverage=<value>
@ -2277,6 +2657,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
-fsanitize-trap=<value> Enable trapping for specified sanitizers
-fsanitize=<check> Turn on runtime checks for various forms of undefined or suspicious
behavior. See user manual for available checks
-fstandalone-debug Emit full debug info for all types used by the program
-gcodeview Generate CodeView debug information
-gline-tables-only Emit debug line number tables only
-miamcu Use Intel MCU ABI

View File

@ -2370,7 +2370,11 @@ enum CXCursorKind {
*/
CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective = 278,
CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective,
/** \brief OpenMP target teams distribute simd directive.
*/
CXCursor_OMPTargetTeamsDistributeSimdDirective = 279,
CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeSimdDirective,
/**
* \brief Cursor that represents the translation unit itself.

View File

@ -2061,6 +2061,10 @@ public:
/// limited representation in the AST.
SourceRange getReturnTypeSourceRange() const;
/// \brief Attempt to compute an informative source range covering the
/// function exception specification, if any.
SourceRange getExceptionSpecSourceRange() const;
/// \brief Determine the type of an expression that calls this function.
QualType getCallResultType() const {
assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");

View File

@ -2028,8 +2028,7 @@ public:
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl);
NamedDecl *Decl);
/// \brief Create an empty class template node.
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);

View File

@ -2672,6 +2672,9 @@ DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {

View File

@ -3711,6 +3711,75 @@ public:
}
};
/// This represents '#pragma omp target teams distribute simd' combined
/// directive.
///
/// \code
/// #pragma omp target teams distribute simd private(x)
/// \endcode
/// In this example directive '#pragma omp target teams distribute simd'
/// has clause 'private' with the variables 'x'
///
class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
SourceLocation EndLoc,
unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
OMPD_target_teams_distribute_simd, StartLoc, EndLoc,
CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
OMPD_target_teams_distribute_simd, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTargetTeamsDistributeSimdDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTargetTeamsDistributeSimdDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
}
};
} // end namespace clang
#endif

View File

@ -1351,6 +1351,19 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
FunctionTypeLoc,
FunctionType,
FunctionLocInfo> {
bool hasExceptionSpec() const {
if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
return FPT->hasExceptionSpec();
}
return false;
}
SourceRange *getExceptionSpecRangePtr() const {
assert(hasExceptionSpec() && "No exception spec range");
// After the Info comes the ParmVarDecl array, and after that comes the
// exception specification information.
return (SourceRange *)(getParmArray() + getNumParams());
}
public:
SourceLocation getLocalRangeBegin() const {
return getLocalData()->LocalRangeBegin;
@ -1384,6 +1397,16 @@ public:
return SourceRange(getLParenLoc(), getRParenLoc());
}
SourceRange getExceptionSpecRange() const {
if (hasExceptionSpec())
return *getExceptionSpecRangePtr();
return SourceRange();
}
void setExceptionSpecRange(SourceRange R) {
if (hasExceptionSpec())
*getExceptionSpecRangePtr() = R;
}
ArrayRef<ParmVarDecl *> getParams() const {
return llvm::makeArrayRef(getParmArray(), getNumParams());
}
@ -1416,12 +1439,15 @@ public:
setLocalRangeEnd(Loc);
for (unsigned i = 0, e = getNumParams(); i != e; ++i)
setParam(i, nullptr);
if (hasExceptionSpec())
setExceptionSpecRange(Loc);
}
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
unsigned getExtraLocalDataSize() const {
return getNumParams() * sizeof(ParmVarDecl *);
unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
}
unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }

View File

@ -386,6 +386,7 @@ warnings or errors at compile-time if calls to the attributed function meet
certain user-defined criteria. For example:
.. code-block:: c
void abs(int a)
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
void must_abs(int a)

View File

@ -8720,10 +8720,6 @@ 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 ext_coroutine_without_co_await_co_yield : ExtWarn<
"'co_return' used in a function "
"that uses neither 'co_await' nor 'co_yield'">,
InGroup<DiagGroup<"coreturn-without-coawait">>;
def err_implied_std_coroutine_traits_not_found : Error<
"you need to include <experimental/coroutine> before defining a coroutine">;
def err_malformed_std_coroutine_traits : Error<

View File

@ -165,6 +165,9 @@
#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name)
#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
@ -218,6 +221,7 @@ OPENMP_DIRECTIVE_EXT(target_teams, "target teams")
OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for_simd, "target teams distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_simd, "target teams distribute simd")
// OpenMP clauses.
OPENMP_CLAUSE(if, OMPIfClause)
@ -446,7 +450,6 @@ OPENMP_TARGET_CLAUSE(firstprivate)
OPENMP_TARGET_CLAUSE(is_device_ptr)
// Clauses allowed for OpenMP directive 'target data'.
// TODO More clauses for 'target data' directive.
OPENMP_TARGET_DATA_CLAUSE(if)
OPENMP_TARGET_DATA_CLAUSE(device)
OPENMP_TARGET_DATA_CLAUSE(map)
@ -483,7 +486,6 @@ OPENMP_TARGET_PARALLEL_CLAUSE(reduction)
OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr)
// Clauses allowed for OpenMP directive 'target parallel for'.
// TODO: add target clauses 'is_device_ptr'
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(device)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(map)
@ -502,9 +504,9 @@ OPENMP_TARGET_PARALLEL_FOR_CLAUSE(collapse)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr)
// Clauses allowed for OpenMP directive 'target update'.
// TODO More clauses for 'target update' directive.
OPENMP_TARGET_UPDATE_CLAUSE(if)
OPENMP_TARGET_UPDATE_CLAUSE(device)
OPENMP_TARGET_UPDATE_CLAUSE(to)
@ -513,7 +515,6 @@ OPENMP_TARGET_UPDATE_CLAUSE(nowait)
OPENMP_TARGET_UPDATE_CLAUSE(depend)
// Clauses allowed for OpenMP directive 'teams'.
// TODO More clauses for 'teams' directive.
OPENMP_TEAMS_CLAUSE(default)
OPENMP_TEAMS_CLAUSE(private)
OPENMP_TEAMS_CLAUSE(firstprivate)
@ -523,7 +524,6 @@ OPENMP_TEAMS_CLAUSE(num_teams)
OPENMP_TEAMS_CLAUSE(thread_limit)
// Clauses allowed for OpenMP directive 'ordered'.
// TODO More clauses for 'ordered' directive.
OPENMP_ORDERED_CLAUSE(threads)
OPENMP_ORDERED_CLAUSE(simd)
OPENMP_ORDERED_CLAUSE(depend)
@ -633,7 +633,6 @@ OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction)
// Clauses allowed for OpenMP directive 'target parallel for simd'.
// TODO: add target clauses 'is_device_ptr'
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(device)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(map)
@ -655,6 +654,7 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(linear)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr)
// Clauses allowed for OpenMP directive 'target simd'.
OPENMP_TARGET_SIMD_CLAUSE(if)
@ -824,6 +824,28 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
// Clauses allowed for OpenMP directive 'target teams distribute simd'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(device)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(map)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nowait)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(depend)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(defaultmap)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(is_device_ptr)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
#undef OPENMP_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_TASKLOOP_CLAUSE
#undef OPENMP_LINEAR_KIND
@ -875,3 +897,4 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE

View File

@ -244,3 +244,4 @@ def OMPTargetTeamsDirective : DStmt<OMPExecutableDirective>;
def OMPTargetTeamsDistributeDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;

View File

@ -27,7 +27,7 @@ class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>;
class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>;
Group<cl_ignored_Group>, Flags<[CLOption, DriverOption]>;
class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
Group<cl_Group>, Flags<[CLOption, DriverOption]>;
@ -299,7 +299,7 @@ def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">;
def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
def _SLASH_FC : CLIgnoredFlag<"FC">;
def _SLASH_Fd : CLIgnoredJoined<"Fd">;
def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">;
def _SLASH_FS : CLIgnoredFlag<"FS">;
def _SLASH_GF : CLIgnoredFlag<"GF">;
def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
def _SLASH_nologo : CLIgnoredFlag<"nologo">;
@ -308,7 +308,8 @@ def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">;
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
def _SLASH_sdl : CLIgnoredFlag<"sdl">;
def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
def _SLASH_utf8 : CLIgnoredFlag<"utf-8">;
def _SLASH_utf8 : CLIgnoredFlag<"utf-8">,
HelpText<"Set source and runtime encoding to UTF-8 (default)">;
def _SLASH_w : CLIgnoredJoined<"w">;
def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">;
def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;

View File

@ -1032,6 +1032,7 @@ def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>,
def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
Flags<[CoreOption]>;
def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>,
HelpText<"Disable delayed template parsing">,
Flags<[DriverOption, CoreOption]>;
def fno_objc_exceptions: Flag<["-"], "fno-objc-exceptions">, Group<f_Group>;
def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;

View File

@ -64,6 +64,8 @@ enum class SymbolSubKind {
None,
CXXCopyConstructor,
CXXMoveConstructor,
AccessorGetter,
AccessorSetter,
};
/// Set of properties that provide additional info about a symbol.
@ -80,7 +82,7 @@ static const unsigned SymbolPropertyBitNum = 7;
typedef unsigned SymbolPropertySet;
/// Set of roles that are attributed to symbol occurrences.
enum class SymbolRole : uint16_t {
enum class SymbolRole : uint32_t {
Declaration = 1 << 0,
Definition = 1 << 1,
Reference = 1 << 2,
@ -99,8 +101,10 @@ enum class SymbolRole : uint16_t {
RelationCalledBy = 1 << 13,
RelationExtendedBy = 1 << 14,
RelationAccessorOf = 1 << 15,
RelationContainedBy = 1 << 16,
RelationIBTypeOf = 1 << 17,
};
static const unsigned SymbolRoleBitNum = 16;
static const unsigned SymbolRoleBitNum = 18;
typedef unsigned SymbolRoleSet;
/// Represents a relation to another symbol for a symbol occurrence.

View File

@ -406,7 +406,8 @@ public:
/// \return false if \#including the file will have no effect or true
/// if we should include it.
bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
bool isImport, Module *CorrespondingModule);
bool isImport, bool ModulesEnabled,
Module *CorrespondingModule);
/// \brief Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.

View File

@ -316,6 +316,14 @@ public:
BuiltinIncludeDir = Dir;
}
/// \brief Get the directory that contains Clang-supplied include files.
const DirectoryEntry *getBuiltinDir() const {
return BuiltinIncludeDir;
}
/// \brief Is this a compiler builtin header?
static bool isBuiltinHeader(StringRef FileName);
/// \brief Add a module map callback.
void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
Callbacks.push_back(std::move(Callback));

View File

@ -600,11 +600,8 @@ private:
public:
// If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
// find a type name by attempting typo correction.
bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false,
bool NeedType = false);
bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
bool NeedType,
CXXScopeSpec &SS,
bool TryAnnotateTypeOrScopeToken();
bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
bool IsNewScope);
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);

View File

@ -1709,7 +1709,8 @@ public:
static bool adjustContextForLocalExternDecl(DeclContext *&DC);
void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
NamedDecl *getShadowedDeclaration(const VarDecl *D, const LookupResult &R);
void CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl, const LookupResult &R);
void CheckShadow(Scope *S, VarDecl *D);
/// Warn if 'E', which is an expression that is about to be modified, refers
@ -1790,9 +1791,8 @@ public:
bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
SourceLocation EqualLoc);
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit,
bool TypeMayContainAuto);
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit);
void ActOnUninitializedDecl(Decl *dcl);
void ActOnInitializerError(Decl *Dcl);
bool canInitializeWithParenthesizedList(QualType TargetType);
@ -1807,8 +1807,7 @@ public:
void FinalizeDeclaration(Decl *D);
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
ArrayRef<Decl *> Group);
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
bool TypeMayContainAuto = true);
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group);
/// Should be called on all declarations that might have attached
/// documentation comments.
@ -4920,8 +4919,7 @@ public:
TypeSourceInfo *AllocTypeInfo,
Expr *ArraySize,
SourceRange DirectInitRange,
Expr *Initializer,
bool TypeMayContainAuto = true);
Expr *Initializer);
bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
SourceRange R);
@ -8584,6 +8582,12 @@ public:
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp target teams distribute simd' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
/// Checks correctness of linear modifiers.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,

View File

@ -1517,6 +1517,7 @@ namespace clang {
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE,
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE,
EXPR_OMP_ARRAY_SECTION,
// ARC

View File

@ -4671,8 +4671,7 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
Loc, Name, TemplateParams,
D2Templated,
/*PrevDecl=*/nullptr);
D2Templated);
D2Templated->setDescribedClassTemplate(D2);
D2->setAccess(D->getAccess());

View File

@ -2990,6 +2990,18 @@ SourceRange FunctionDecl::getReturnTypeSourceRange() const {
return RTRange;
}
SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
const TypeSourceInfo *TSI = getTypeSourceInfo();
if (!TSI)
return SourceRange();
FunctionTypeLoc FTL =
TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
if (!FTL)
return SourceRange();
return FTL.getExceptionSpecRange();
}
const Attr *FunctionDecl::getUnusedResultAttr() const {
QualType RetType = getReturnType();
if (RetType->isRecordType()) {

View File

@ -297,12 +297,10 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl) {
NamedDecl *Decl) {
AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
Params, Decl);
New->setPreviousDecl(PrevDecl);
return New;
}

View File

@ -562,8 +562,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
FT = dyn_cast<FunctionProtoType>(AFT);
if (IT == FuncSig) {
assert(FT && "We must have a written prototype in this case.");
switch (FT->getCallConv()) {
switch (AFT->getCallConv()) {
case CC_C: POut << "__cdecl "; break;
case CC_X86StdCall: POut << "__stdcall "; break;
case CC_X86FastCall: POut << "__fastcall "; break;
@ -587,12 +586,15 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
if (FT->isVariadic()) {
if (FD->getNumParams()) POut << ", ";
POut << "...";
} else if ((IT == FuncSig || !Context.getLangOpts().CPlusPlus) &&
!Decl->getNumParams()) {
POut << "void";
}
}
POut << ")";
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
const FunctionType *FT = MD->getType()->castAs<FunctionType>();
assert(FT && "We must have a written prototype in this case.");
if (FT->isConst())
POut << " const";
if (FT->isVolatile())

View File

@ -1627,8 +1627,17 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
// C++1y: A constant initializer for an object o [...] may also invoke
// constexpr constructors for o and its subobjects even if those objects
// are of non-literal class types.
if (Info.getLangOpts().CPlusPlus14 && This &&
Info.EvaluatingDecl == This->getLValueBase())
//
// C++11 missed this detail for aggregates, so classes like this:
// struct foo_t { union { int i; volatile int j; } u; };
// are not (obviously) initializable like so:
// __attribute__((__require_constant_initialization__))
// static const foo_t x = {{0}};
// because "i" is a subobject with non-literal initialization (due to the
// volatile member of the union). See:
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677
// Therefore, we use the C++1y behavior.
if (This && Info.EvaluatingDecl == This->getLValueBase())
return true;
// Prvalue constant expressions must be of literal types.

View File

@ -1720,3 +1720,59 @@ OMPTargetTeamsDistributeParallelForSimdDirective::CreateEmpty(
CollapsedNum, NumClauses);
}
OMPTargetTeamsDistributeSimdDirective *
OMPTargetTeamsDistributeSimdDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
const HelperExprs &Exprs) {
auto Size = llvm::alignTo(sizeof(OMPTargetTeamsDistributeSimdDirective),
alignof(OMPClause *));
void *Mem = C.Allocate(
Size + sizeof(OMPClause *) * Clauses.size() +
sizeof(Stmt *) *
numLoopChildren(CollapsedNum, OMPD_target_teams_distribute_simd));
OMPTargetTeamsDistributeSimdDirective *Dir = new (Mem)
OMPTargetTeamsDistributeSimdDirective(StartLoc, EndLoc, CollapsedNum,
Clauses.size());
Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
Dir->setIterationVariable(Exprs.IterationVarRef);
Dir->setLastIteration(Exprs.LastIteration);
Dir->setCalcLastIteration(Exprs.CalcLastIteration);
Dir->setPreCond(Exprs.PreCond);
Dir->setCond(Exprs.Cond);
Dir->setInit(Exprs.Init);
Dir->setInc(Exprs.Inc);
Dir->setIsLastIterVariable(Exprs.IL);
Dir->setLowerBoundVariable(Exprs.LB);
Dir->setUpperBoundVariable(Exprs.UB);
Dir->setStrideVariable(Exprs.ST);
Dir->setEnsureUpperBound(Exprs.EUB);
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
return Dir;
}
OMPTargetTeamsDistributeSimdDirective *
OMPTargetTeamsDistributeSimdDirective::CreateEmpty(const ASTContext &C,
unsigned NumClauses,
unsigned CollapsedNum,
EmptyShell) {
auto Size = llvm::alignTo(sizeof(OMPTargetTeamsDistributeSimdDirective),
alignof(OMPClause *));
void *Mem = C.Allocate(
Size + sizeof(OMPClause *) * NumClauses +
sizeof(Stmt *) *
numLoopChildren(CollapsedNum, OMPD_target_teams_distribute_simd));
return new (Mem)
OMPTargetTeamsDistributeSimdDirective(CollapsedNum, NumClauses);
}

View File

@ -1250,6 +1250,12 @@ void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
PrintOMPExecutableDirective(Node);
}
void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
OMPTargetTeamsDistributeSimdDirective *Node) {
Indent() << "#pragma omp target teams distribute simd ";
PrintOMPExecutableDirective(Node);
}
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//

View File

@ -768,6 +768,11 @@ void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
VisitOMPLoopDirective(S);
}
void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
const OMPTargetTeamsDistributeSimdDirective *S) {
VisitOMPLoopDirective(S);
}
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}

View File

@ -467,6 +467,8 @@ static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
ASTMaker M(Ctx);
const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl();
if (!selfVar)
return nullptr;
Expr *loadedIVar =
M.makeObjCIvarRef(

View File

@ -2175,19 +2175,15 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
// Create local scope for C++17 if init-stmt if one exists.
if (Stmt *Init = I->getInit()) {
LocalScope::const_iterator BeginScopePos = ScopePos;
if (Stmt *Init = I->getInit())
addLocalScopeForStmt(Init);
addAutomaticObjDtors(ScopePos, BeginScopePos, I);
}
// Create local scope for possible condition variable.
// Store scope position. Add implicit destructor.
if (VarDecl *VD = I->getConditionVariable()) {
LocalScope::const_iterator BeginScopePos = ScopePos;
if (VarDecl *VD = I->getConditionVariable())
addLocalScopeForVarDecl(VD);
addAutomaticObjDtors(ScopePos, BeginScopePos, I);
}
addAutomaticObjDtors(ScopePos, save_scope_pos.get(), I);
// The block we were processing is now finished. Make it the successor
// block.
@ -2256,36 +2252,39 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
// removes infeasible paths from the control-flow graph by having the
// control-flow transfer of '&&' or '||' go directly into the then/else
// blocks directly.
if (!I->getConditionVariable())
if (BinaryOperator *Cond =
dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens()))
if (Cond->isLogicalOp())
return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first;
BinaryOperator *Cond =
I->getConditionVariable()
? nullptr
: dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens());
CFGBlock *LastBlock;
if (Cond && Cond->isLogicalOp())
LastBlock = VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first;
else {
// Now create a new block containing the if statement.
Block = createBlock(false);
// Now create a new block containing the if statement.
Block = createBlock(false);
// Set the terminator of the new block to the If statement.
Block->setTerminator(I);
// Set the terminator of the new block to the If statement.
Block->setTerminator(I);
// See if this is a known constant.
const TryResult &KnownVal = tryEvaluateBool(I->getCond());
// See if this is a known constant.
const TryResult &KnownVal = tryEvaluateBool(I->getCond());
// Add the successors. If we know that specific branches are
// unreachable, inform addSuccessor() of that knowledge.
addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse());
addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue());
// Add the successors. If we know that specific branches are
// unreachable, inform addSuccessor() of that knowledge.
addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse());
addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue());
// Add the condition as the last statement in the new block. This may
// create new blocks as the condition may contain control-flow. Any newly
// created blocks will be pointed to be "Block".
LastBlock = addStmt(I->getCond());
// Add the condition as the last statement in the new block. This may create
// new blocks as the condition may contain control-flow. Any newly created
// blocks will be pointed to be "Block".
CFGBlock *LastBlock = addStmt(I->getCond());
// If the IfStmt contains a condition variable, add it and its
// initializer to the CFG.
if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) {
autoCreateBlock();
LastBlock = addStmt(const_cast<DeclStmt *>(DS));
// If the IfStmt contains a condition variable, add it and its
// initializer to the CFG.
if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) {
autoCreateBlock();
LastBlock = addStmt(const_cast<DeclStmt *>(DS));
}
}
// Finally, if the IfStmt contains a C++17 init-stmt, add it to the CFG.
@ -3078,19 +3077,15 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
// Create local scope for C++17 switch init-stmt if one exists.
if (Stmt *Init = Terminator->getInit()) {
LocalScope::const_iterator BeginScopePos = ScopePos;
if (Stmt *Init = Terminator->getInit())
addLocalScopeForStmt(Init);
addAutomaticObjDtors(ScopePos, BeginScopePos, Terminator);
}
// Create local scope for possible condition variable.
// Store scope position. Add implicit destructor.
if (VarDecl *VD = Terminator->getConditionVariable()) {
LocalScope::const_iterator SwitchBeginScopePos = ScopePos;
if (VarDecl *VD = Terminator->getConditionVariable())
addLocalScopeForVarDecl(VD);
addAutomaticObjDtors(ScopePos, SwitchBeginScopePos, Terminator);
}
addAutomaticObjDtors(ScopePos, save_scope_pos.get(), Terminator);
if (Block) {
if (badCFG)

View File

@ -218,11 +218,21 @@ static bool isConfigurationValue(const Stmt *S,
}
case Stmt::UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(S);
if (SilenceableCondVal)
*SilenceableCondVal = UO->getSourceRange();
return UO->getOpcode() == UO_LNot &&
isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal,
IncludeIntegers, WrappedInParens);
if (UO->getOpcode() != UO_LNot)
return false;
bool SilenceableCondValNotSet =
SilenceableCondVal && SilenceableCondVal->getBegin().isInvalid();
bool IsSubExprConfigValue =
isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal,
IncludeIntegers, WrappedInParens);
// Update the silenceable condition value source range only if the range
// was set directly by the child expression.
if (SilenceableCondValNotSet &&
SilenceableCondVal->getBegin().isValid() &&
*SilenceableCondVal ==
UO->getSubExpr()->IgnoreCasts()->getSourceRange())
*SilenceableCondVal = UO->getSourceRange();
return IsSubExprConfigValue;
}
default:
return false;

View File

@ -695,6 +695,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \
case OMPC_##Name: \
return true;
#include "clang/Basic/OpenMPKinds.def"
default:
break;
}
break;
case OMPD_target_teams_distribute_simd:
switch (CKind) {
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \
case OMPC_##Name: \
return true;
#include "clang/Basic/OpenMPKinds.def"
default:
break;
@ -732,7 +742,8 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd;
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd;
}
bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
@ -773,7 +784,8 @@ bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd;
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd;
}
bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
@ -792,7 +804,8 @@ bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
return isOpenMPNestingTeamsDirective(DKind) ||
DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd;
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd;
}
bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
@ -802,7 +815,8 @@ bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_distribute_simd || DKind == OMPD_target_simd ||
DKind == OMPD_teams_distribute_simd ||
DKind == OMPD_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_parallel_for_simd;
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd;
}
bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
@ -819,7 +833,8 @@ bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
Kind == OMPD_teams_distribute_parallel_for ||
Kind == OMPD_target_teams_distribute ||
Kind == OMPD_target_teams_distribute_parallel_for ||
Kind == OMPD_target_teams_distribute_parallel_for_simd;
Kind == OMPD_target_teams_distribute_parallel_for_simd ||
Kind == OMPD_target_teams_distribute_simd;
}
bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
@ -845,5 +860,6 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
Kind == OMPD_teams_distribute_parallel_for ||
Kind == OMPD_target_teams_distribute ||
Kind == OMPD_target_teams_distribute_parallel_for ||
Kind == OMPD_target_teams_distribute_parallel_for_simd;
Kind == OMPD_target_teams_distribute_parallel_for_simd ||
Kind == OMPD_target_teams_distribute_simd;
}

View File

@ -2663,6 +2663,12 @@ class X86TargetInfo : public TargetInfo {
CK_BDVER4,
//@}
/// \name zen
/// Zen architecture processors.
//@{
CK_ZNVER1,
//@}
/// This specification is deprecated and will be removed in the future.
/// Users should prefer \see CK_K8.
// FIXME: Warn on this when the CPU is set to it.
@ -2744,6 +2750,7 @@ class X86TargetInfo : public TargetInfo {
.Case("bdver2", CK_BDVER2)
.Case("bdver3", CK_BDVER3)
.Case("bdver4", CK_BDVER4)
.Case("znver1", CK_ZNVER1)
.Case("x86-64", CK_x86_64)
.Case("geode", CK_Geode)
.Default(CK_Generic);
@ -2943,6 +2950,7 @@ public:
case CK_BDVER2:
case CK_BDVER3:
case CK_BDVER4:
case CK_ZNVER1:
case CK_x86_64:
return true;
}
@ -3190,6 +3198,33 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "cx16", true);
setFeatureEnabledImpl(Features, "fxsr", true);
break;
case CK_ZNVER1:
setFeatureEnabledImpl(Features, "adx", true);
setFeatureEnabledImpl(Features, "aes", true);
setFeatureEnabledImpl(Features, "avx2", true);
setFeatureEnabledImpl(Features, "bmi", true);
setFeatureEnabledImpl(Features, "bmi2", true);
setFeatureEnabledImpl(Features, "clflushopt", true);
setFeatureEnabledImpl(Features, "cx16", true);
setFeatureEnabledImpl(Features, "f16c", true);
setFeatureEnabledImpl(Features, "fma", true);
setFeatureEnabledImpl(Features, "fsgsbase", true);
setFeatureEnabledImpl(Features, "fxsr", true);
setFeatureEnabledImpl(Features, "lzcnt", true);
setFeatureEnabledImpl(Features, "mwaitx", true);
setFeatureEnabledImpl(Features, "movbe", true);
setFeatureEnabledImpl(Features, "pclmul", true);
setFeatureEnabledImpl(Features, "popcnt", true);
setFeatureEnabledImpl(Features, "prfchw", true);
setFeatureEnabledImpl(Features, "rdrnd", true);
setFeatureEnabledImpl(Features, "rdseed", true);
setFeatureEnabledImpl(Features, "sha", true);
setFeatureEnabledImpl(Features, "sse4a", true);
setFeatureEnabledImpl(Features, "xsave", true);
setFeatureEnabledImpl(Features, "xsavec", true);
setFeatureEnabledImpl(Features, "xsaveopt", true);
setFeatureEnabledImpl(Features, "xsaves", true);
break;
case CK_BDVER4:
setFeatureEnabledImpl(Features, "avx2", true);
setFeatureEnabledImpl(Features, "bmi2", true);
@ -3741,6 +3776,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_BDVER4:
defineCPUMacros(Builder, "bdver4");
break;
case CK_ZNVER1:
defineCPUMacros(Builder, "znver1");
break;
case CK_Geode:
defineCPUMacros(Builder, "geode");
break;

View File

@ -36,7 +36,7 @@ std::string getClangRepositoryPath() {
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $");
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_40/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));

View File

@ -4318,9 +4318,9 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
}
if (BuiltinID == ARM::BI__builtin_arm_rbit) {
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_rbit),
EmitScalarExpr(E->getArg(0)),
"rbit");
llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
}
if (BuiltinID == ARM::BI__clear_cache) {
@ -5226,14 +5226,14 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
"rbit of unusual size!");
llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
}
if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
assert((getContext().getTypeSize(E->getType()) == 64) &&
"rbit of unusual size!");
llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
}
if (BuiltinID == AArch64::BI__clear_cache) {

View File

@ -311,7 +311,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
if (!Init) {
if (!getLangOpts().CPlusPlus)
CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
else if (Builder.GetInsertBlock()) {
else if (HaveInsertPoint()) {
// Since we have a static initializer, this global variable can't
// be constant.
GV->setConstant(false);
@ -352,7 +352,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
GV->setConstant(CGM.isTypeConstant(D.getType(), true));
GV->setInitializer(Init);
if (hasNontrivialDestruction(D.getType())) {
if (hasNontrivialDestruction(D.getType()) && HaveInsertPoint()) {
// We have a constant initializer, but a nontrivial destructor. We still
// need to perform a guarded "initialization" in order to register the
// destructor.

View File

@ -353,9 +353,6 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
if (D->getTLSKind()) {
// FIXME: Should we support init_priority for thread_local?
// FIXME: Ideally, initialization of instantiated thread_local static data
// members of class templates should not trigger initialization of other
// entities in the TU.
// FIXME: We only need to register one __cxa_thread_atexit function for the
// entire TU.
CXXThreadLocalInits.push_back(Fn);

View File

@ -99,10 +99,11 @@ class CGOpenMPOutlinedRegionInfo final : public CGOpenMPRegionInfo {
public:
CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
const RegionCodeGenTy &CodeGen,
OpenMPDirectiveKind Kind, bool HasCancel)
OpenMPDirectiveKind Kind, bool HasCancel,
StringRef HelperName)
: CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
HasCancel),
ThreadIDVar(ThreadIDVar) {
ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
}
@ -111,7 +112,7 @@ public:
const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
/// \brief Get the name of the capture helper.
StringRef getHelperName() const override { return ".omp_outlined."; }
StringRef getHelperName() const override { return HelperName; }
static bool classof(const CGCapturedStmtInfo *Info) {
return CGOpenMPRegionInfo::classof(Info) &&
@ -123,6 +124,7 @@ private:
/// \brief A variable or parameter storing global thread id for OpenMP
/// constructs.
const VarDecl *ThreadIDVar;
StringRef HelperName;
};
/// \brief API for captured statement code generation in OpenMP constructs.
@ -855,7 +857,7 @@ llvm::Value *CGOpenMPRuntime::emitParallelOrTeamsOutlinedFunction(
else if (auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
HasCancel = OPFD->hasCancel();
CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
HasCancel);
HasCancel, getOutlinedHelperName());
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
}
@ -1892,9 +1894,9 @@ llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
/// } else {
/// ElseGen();
/// }
static void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
const RegionCodeGenTy &ThenGen,
const RegionCodeGenTy &ElseGen) {
void CGOpenMPRuntime::emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
const RegionCodeGenTy &ThenGen,
const RegionCodeGenTy &ElseGen) {
CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
// If the condition constant folds and can be elided, try to avoid emitting

View File

@ -130,6 +130,35 @@ protected:
bool IsOffloadEntry,
const RegionCodeGenTy &CodeGen);
/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
/// function. Here is the logic:
/// if (Cond) {
/// ThenGen();
/// } else {
/// ElseGen();
/// }
void emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
const RegionCodeGenTy &ThenGen,
const RegionCodeGenTy &ElseGen);
/// \brief Emits object of ident_t type with info for source location.
/// \param Flags Flags for OpenMP location.
///
llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
unsigned Flags = 0);
/// \brief Returns pointer to ident_t type.
llvm::Type *getIdentTyPointerTy();
/// \brief Gets thread id value for the current thread.
///
llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
/// \brief Get the function name of an outlined region.
// The name can be customized depending on the target.
//
virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
private:
/// \brief Default const ident_t object used for initialization of all other
/// ident_t objects.
@ -388,15 +417,6 @@ private:
/// \brief Build type kmp_routine_entry_t (if not built yet).
void emitKmpRoutineEntryT(QualType KmpInt32Ty);
/// \brief Emits object of ident_t type with info for source location.
/// \param Flags Flags for OpenMP location.
///
llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
unsigned Flags = 0);
/// \brief Returns pointer to ident_t type.
llvm::Type *getIdentTyPointerTy();
/// \brief Returns pointer to kmpc_micro type.
llvm::Type *getKmpc_MicroPointerTy();
@ -432,10 +452,6 @@ private:
/// stored.
virtual Address emitThreadIDAddress(CodeGenFunction &CGF, SourceLocation Loc);
/// \brief Gets thread id value for the current thread.
///
llvm::Value *getThreadID(CodeGenFunction &CGF, SourceLocation Loc);
/// \brief Gets (if variable with the given name already exist) or creates
/// internal global variable with the specified Name. The created variable has
/// linkage CommonLinkage by default and is initialized by null value.

View File

@ -26,8 +26,57 @@ enum OpenMPRTLFunctionNVPTX {
OMPRTL_NVPTX__kmpc_kernel_init,
/// \brief Call to void __kmpc_kernel_deinit();
OMPRTL_NVPTX__kmpc_kernel_deinit,
/// \brief Call to void __kmpc_kernel_prepare_parallel(void
/// *outlined_function);
OMPRTL_NVPTX__kmpc_kernel_prepare_parallel,
/// \brief Call to bool __kmpc_kernel_parallel(void **outlined_function);
OMPRTL_NVPTX__kmpc_kernel_parallel,
/// \brief Call to void __kmpc_kernel_end_parallel();
OMPRTL_NVPTX__kmpc_kernel_end_parallel,
/// Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
/// global_tid);
OMPRTL_NVPTX__kmpc_serialized_parallel,
/// Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
/// global_tid);
OMPRTL_NVPTX__kmpc_end_serialized_parallel,
};
} // namespace
/// Pre(post)-action for different OpenMP constructs specialized for NVPTX.
class NVPTXActionTy final : public PrePostActionTy {
llvm::Value *EnterCallee;
ArrayRef<llvm::Value *> EnterArgs;
llvm::Value *ExitCallee;
ArrayRef<llvm::Value *> ExitArgs;
bool Conditional;
llvm::BasicBlock *ContBlock = nullptr;
public:
NVPTXActionTy(llvm::Value *EnterCallee, ArrayRef<llvm::Value *> EnterArgs,
llvm::Value *ExitCallee, ArrayRef<llvm::Value *> ExitArgs,
bool Conditional = false)
: EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
ExitArgs(ExitArgs), Conditional(Conditional) {}
void Enter(CodeGenFunction &CGF) override {
llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
if (Conditional) {
llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
ContBlock = CGF.createBasicBlock("omp_if.end");
// Generate the branch (If-stmt)
CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
CGF.EmitBlock(ThenBlock);
}
}
void Done(CodeGenFunction &CGF) {
// Emit the rest of blocks/branches
CGF.EmitBranch(ContBlock);
CGF.EmitBlock(ContBlock, true);
}
void Exit(CodeGenFunction &CGF) override {
CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
}
};
} // anonymous namespace
/// Get the GPU warp size.
static llvm::Value *getNVPTXWarpSize(CodeGenFunction &CGF) {
@ -118,6 +167,7 @@ void CGOpenMPRuntimeNVPTX::emitGenericKernel(const OMPExecutableDirective &D,
const RegionCodeGenTy &CodeGen) {
EntryFunctionState EST;
WorkerFunctionState WST(CGM);
Work.clear();
// Emit target region as a standalone region.
class NVPTXPrePostActionTy : public PrePostActionTy {
@ -246,7 +296,10 @@ void CGOpenMPRuntimeNVPTX::emitWorkerLoop(CodeGenFunction &CGF,
CGF.InitTempAlloca(ExecStatus, Bld.getInt8(/*C=*/0));
CGF.InitTempAlloca(WorkFn, llvm::Constant::getNullValue(CGF.Int8PtrTy));
// TODO: Call into runtime to get parallel work.
llvm::Value *Args[] = {WorkFn.getPointer()};
llvm::Value *Ret = CGF.EmitRuntimeCall(
createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_parallel), Args);
Bld.CreateStore(Bld.CreateZExt(Ret, CGF.Int8Ty), ExecStatus);
// On termination condition (workid == 0), exit loop.
llvm::Value *ShouldTerminate =
@ -261,10 +314,42 @@ void CGOpenMPRuntimeNVPTX::emitWorkerLoop(CodeGenFunction &CGF,
// Signal start of parallel region.
CGF.EmitBlock(ExecuteBB);
// TODO: Add parallel work.
// Process work items: outlined parallel functions.
for (auto *W : Work) {
// Try to match this outlined function.
auto *ID = Bld.CreatePointerBitCastOrAddrSpaceCast(W, CGM.Int8PtrTy);
llvm::Value *WorkFnMatch =
Bld.CreateICmpEQ(Bld.CreateLoad(WorkFn), ID, "work_match");
llvm::BasicBlock *ExecuteFNBB = CGF.createBasicBlock(".execute.fn");
llvm::BasicBlock *CheckNextBB = CGF.createBasicBlock(".check.next");
Bld.CreateCondBr(WorkFnMatch, ExecuteFNBB, CheckNextBB);
// Execute this outlined function.
CGF.EmitBlock(ExecuteFNBB);
// Insert call to work function.
// FIXME: Pass arguments to outlined function from master thread.
auto *Fn = cast<llvm::Function>(W);
Address ZeroAddr =
CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, /*Name=*/".zero.addr");
CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C=*/0));
llvm::Value *FnArgs[] = {ZeroAddr.getPointer(), ZeroAddr.getPointer()};
CGF.EmitCallOrInvoke(Fn, FnArgs);
// Go to end of parallel region.
CGF.EmitBranch(TerminateBB);
CGF.EmitBlock(CheckNextBB);
}
// Signal end of parallel region.
CGF.EmitBlock(TerminateBB);
CGF.EmitRuntimeCall(
createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_end_parallel),
llvm::None);
CGF.EmitBranch(BarrierBB);
// All active and inactive workers wait at a barrier after parallel region.
@ -296,10 +381,53 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
case OMPRTL_NVPTX__kmpc_kernel_deinit: {
// Build void __kmpc_kernel_deinit();
llvm::FunctionType *FnTy =
llvm::FunctionType::get(CGM.VoidTy, {}, /*isVarArg*/ false);
llvm::FunctionType::get(CGM.VoidTy, llvm::None, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_deinit");
break;
}
case OMPRTL_NVPTX__kmpc_kernel_prepare_parallel: {
/// Build void __kmpc_kernel_prepare_parallel(
/// void *outlined_function);
llvm::Type *TypeParams[] = {CGM.Int8PtrTy};
llvm::FunctionType *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_prepare_parallel");
break;
}
case OMPRTL_NVPTX__kmpc_kernel_parallel: {
/// Build bool __kmpc_kernel_parallel(void **outlined_function);
llvm::Type *TypeParams[] = {CGM.Int8PtrPtrTy};
llvm::Type *RetTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
llvm::FunctionType *FnTy =
llvm::FunctionType::get(RetTy, TypeParams, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_parallel");
break;
}
case OMPRTL_NVPTX__kmpc_kernel_end_parallel: {
/// Build void __kmpc_kernel_end_parallel();
llvm::FunctionType *FnTy =
llvm::FunctionType::get(CGM.VoidTy, llvm::None, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_end_parallel");
break;
}
case OMPRTL_NVPTX__kmpc_serialized_parallel: {
// Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
// global_tid);
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
llvm::FunctionType *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
break;
}
case OMPRTL_NVPTX__kmpc_end_serialized_parallel: {
// Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
// global_tid);
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
llvm::FunctionType *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
break;
}
}
return RTLFn;
}
@ -362,9 +490,12 @@ llvm::Value *CGOpenMPRuntimeNVPTX::emitParallelOrTeamsOutlinedFunction(
OutlinedFun = cast<llvm::Function>(OutlinedFunVal);
OutlinedFun->removeFnAttr(llvm::Attribute::NoInline);
OutlinedFun->addFnAttr(llvm::Attribute::AlwaysInline);
} else
llvm_unreachable("parallel directive is not yet supported for nvptx "
"backend.");
} else {
llvm::Value *OutlinedFunVal =
CGOpenMPRuntime::emitParallelOrTeamsOutlinedFunction(
D, ThreadIDVar, InnermostKind, CodeGen);
OutlinedFun = cast<llvm::Function>(OutlinedFunVal);
}
return OutlinedFun;
}
@ -387,3 +518,81 @@ void CGOpenMPRuntimeNVPTX::emitTeamsCall(CodeGenFunction &CGF,
OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
}
void CGOpenMPRuntimeNVPTX::emitParallelCall(
CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
if (!CGF.HaveInsertPoint())
return;
emitGenericParallelCall(CGF, Loc, OutlinedFn, CapturedVars, IfCond);
}
void CGOpenMPRuntimeNVPTX::emitGenericParallelCall(
CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
llvm::Function *Fn = cast<llvm::Function>(OutlinedFn);
auto &&L0ParallelGen = [this, Fn, &CapturedVars](CodeGenFunction &CGF,
PrePostActionTy &) {
CGBuilderTy &Bld = CGF.Builder;
// Prepare for parallel region. Indicate the outlined function.
llvm::Value *Args[] = {Bld.CreateBitOrPointerCast(Fn, CGM.Int8PtrTy)};
CGF.EmitRuntimeCall(
createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_prepare_parallel),
Args);
// Activate workers. This barrier is used by the master to signal
// work for the workers.
syncCTAThreads(CGF);
// OpenMP [2.5, Parallel Construct, p.49]
// There is an implied barrier at the end of a parallel region. After the
// end of a parallel region, only the master thread of the team resumes
// execution of the enclosing task region.
//
// The master waits at this barrier until all workers are done.
syncCTAThreads(CGF);
// Remember for post-processing in worker loop.
Work.push_back(Fn);
};
auto *RTLoc = emitUpdateLocation(CGF, Loc);
auto *ThreadID = getThreadID(CGF, Loc);
llvm::Value *Args[] = {RTLoc, ThreadID};
auto &&SeqGen = [this, Fn, &CapturedVars, &Args](CodeGenFunction &CGF,
PrePostActionTy &) {
auto &&CodeGen = [this, Fn, &CapturedVars, &Args](CodeGenFunction &CGF,
PrePostActionTy &Action) {
Action.Enter(CGF);
llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
OutlinedFnArgs.push_back(
llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
OutlinedFnArgs.push_back(
llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
CGF.EmitCallOrInvoke(Fn, OutlinedFnArgs);
};
RegionCodeGenTy RCG(CodeGen);
NVPTXActionTy Action(
createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_serialized_parallel),
Args,
createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_end_serialized_parallel),
Args);
RCG.setAction(Action);
RCG(CGF);
};
if (IfCond)
emitOMPIfClause(CGF, IfCond, L0ParallelGen, SeqGen);
else {
CodeGenFunction::RunCleanupsScope Scope(CGF);
RegionCodeGenTy ThenRCG(L0ParallelGen);
ThenRCG(CGF);
}
}

View File

@ -25,6 +25,9 @@ namespace CodeGen {
class CGOpenMPRuntimeNVPTX : public CGOpenMPRuntime {
private:
// Parallel outlined function work for workers to execute.
llvm::SmallVector<llvm::Function *, 16> Work;
struct EntryFunctionState {
llvm::BasicBlock *ExitBB = nullptr;
};
@ -100,6 +103,29 @@ private:
bool IsOffloadEntry,
const RegionCodeGenTy &CodeGen) override;
/// \brief Emits code for parallel or serial call of the \a OutlinedFn with
/// variables captured in a record which address is stored in \a
/// CapturedStruct.
/// This call is for the Generic Execution Mode.
/// \param OutlinedFn Outlined function to be run in parallel threads. Type of
/// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
/// \param CapturedVars A pointer to the record with the references to
/// variables used in \a OutlinedFn function.
/// \param IfCond Condition in the associated 'if' clause, if it was
/// specified, nullptr otherwise.
void emitGenericParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond);
protected:
/// \brief Get the function name of an outlined region.
// The name can be customized depending on the target.
//
StringRef getOutlinedHelperName() const override {
return "__omp_outlined__";
}
public:
explicit CGOpenMPRuntimeNVPTX(CodeGenModule &CGM);
@ -137,6 +163,20 @@ public:
void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
SourceLocation Loc, llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) override;
/// \brief Emits code for parallel or serial call of the \a OutlinedFn with
/// variables captured in a record which address is stored in \a
/// CapturedStruct.
/// \param OutlinedFn Outlined function to be run in parallel threads. Type of
/// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
/// \param CapturedVars A pointer to the record with the references to
/// variables used in \a OutlinedFn function.
/// \param IfCond Condition in the associated 'if' clause, if it was
/// specified, nullptr otherwise.
void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) override;
};
} // CodeGen namespace.

View File

@ -330,6 +330,10 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
EmitOMPTargetTeamsDistributeParallelForSimdDirective(
cast<OMPTargetTeamsDistributeParallelForSimdDirective>(*S));
break;
case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
EmitOMPTargetTeamsDistributeSimdDirective(
cast<OMPTargetTeamsDistributeSimdDirective>(*S));
break;
}
}

View File

@ -2042,6 +2042,16 @@ void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
});
}
void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
const OMPTargetTeamsDistributeSimdDirective &S) {
CGM.getOpenMPRuntime().emitInlinedDirective(
*this, OMPD_target_teams_distribute_simd,
[&S](CodeGenFunction &CGF, PrePostActionTy &) {
CGF.EmitStmt(
cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
});
}
/// \brief Emit a helper variable and return corresponding lvalue.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
const DeclRefExpr *Helper) {

View File

@ -2701,6 +2701,8 @@ public:
const OMPTargetTeamsDistributeParallelForDirective &S);
void EmitOMPTargetTeamsDistributeParallelForSimdDirective(
const OMPTargetTeamsDistributeParallelForSimdDirective &S);
void EmitOMPTargetTeamsDistributeSimdDirective(
const OMPTargetTeamsDistributeSimdDirective &S);
/// Emit outlined function for the target directive.
static std::pair<llvm::Function * /*OutlinedFn*/,

View File

@ -1243,9 +1243,15 @@ void CodeGenModule::EmitModuleLinkOptions() {
SmallVector<clang::Module *, 16> Stack;
// Seed the stack with imported modules.
for (Module *M : ImportedModules)
for (Module *M : ImportedModules) {
// Do not add any link flags when an implementation TU of a module imports
// a header of that same module.
if (M->getTopLevelModuleName() == getLangOpts().CurrentModule &&
!getLangOpts().isCompilingModule())
continue;
if (Visited.insert(M).second)
Stack.push_back(M);
}
// Find all of the modules to import, making a little effort to prune
// non-leaf modules.

View File

@ -2272,7 +2272,21 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
ArrayRef<llvm::Function *> CXXThreadLocalInits,
ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
llvm::Function *InitFunc = nullptr;
if (!CXXThreadLocalInits.empty()) {
// Separate initializers into those with ordered (or partially-ordered)
// initialization and those with unordered initialization.
llvm::SmallVector<llvm::Function *, 8> OrderedInits;
llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
for (unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
if (isTemplateInstantiation(
CXXThreadLocalInitVars[I]->getTemplateSpecializationKind()))
UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
CXXThreadLocalInits[I];
else
OrderedInits.push_back(CXXThreadLocalInits[I]);
}
if (!OrderedInits.empty()) {
// Generate a guarded initialization function.
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
@ -2289,24 +2303,28 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
CharUnits GuardAlign = CharUnits::One();
Guard->setAlignment(GuardAlign.getQuantity());
CodeGenFunction(CGM)
.GenerateCXXGlobalInitFunc(InitFunc, CXXThreadLocalInits,
Address(Guard, GuardAlign));
CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, OrderedInits,
Address(Guard, GuardAlign));
// On Darwin platforms, use CXX_FAST_TLS calling convention.
if (CGM.getTarget().getTriple().isOSDarwin()) {
InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
}
}
// Emit thread wrappers.
for (const VarDecl *VD : CXXThreadLocals) {
llvm::GlobalVariable *Var =
cast<llvm::GlobalVariable>(CGM.GetGlobalValue(CGM.getMangledName(VD)));
llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
// Some targets require that all access to thread local variables go through
// the thread wrapper. This means that we cannot attempt to create a thread
// wrapper or a thread helper.
if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition())
if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition()) {
Wrapper->setLinkage(llvm::Function::ExternalLinkage);
continue;
}
// Mangle the name for the thread_local initialization function.
SmallString<256> InitFnName;
@ -2322,18 +2340,21 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
bool InitIsInitFunc = false;
if (VD->hasDefinition()) {
InitIsInitFunc = true;
if (InitFunc)
llvm::Function *InitFuncToUse = InitFunc;
if (isTemplateInstantiation(VD->getTemplateSpecializationKind()))
InitFuncToUse = UnorderedInits.lookup(VD->getCanonicalDecl());
if (InitFuncToUse)
Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
InitFunc);
InitFuncToUse);
} else {
// Emit a weak global function referring to the initialization function.
// This function will not exist if the TU defining the thread_local
// variable in question does not need any dynamic initialization for
// its thread_local variables.
llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false);
Init = llvm::Function::Create(
FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
&CGM.getModule());
Init = llvm::Function::Create(FnTy,
llvm::GlobalVariable::ExternalWeakLinkage,
InitFnName.str(), &CGM.getModule());
const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
CGM.SetLLVMFunctionAttributes(nullptr, FI, cast<llvm::Function>(Init));
}
@ -2341,7 +2362,6 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
if (Init)
Init->setVisibility(Var->getVisibility());
llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
llvm::LLVMContext &Context = CGM.getModule().getContext();
llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper);
CGBuilderTy Builder(CGM, Entry);

View File

@ -1531,7 +1531,7 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
static const char *const AArch64Triples[] = {
"aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android",
"aarch64-redhat-linux"};
"aarch64-redhat-linux", "aarch64-suse-linux"};
static const char *const AArch64beLibDirs[] = {"/lib"};
static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
"aarch64_be-linux-gnu"};

View File

@ -6431,11 +6431,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->claim();
// We translate this by hand to the -cc1 argument, since nightly test uses
// it and developers have been trained to spell it with -mllvm.
if (StringRef(A->getValue(0)) == "-disable-llvm-passes") {
CmdArgs.push_back("-disable-llvm-passes");
} else
// it and developers have been trained to spell it with -mllvm. Both
// spellings are now deprecated and should be removed.
if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
CmdArgs.push_back("-disable-llvm-optzns");
} else {
A->render(Args, CmdArgs);
}
}
// With -save-temps, we want to save the unoptimized bitcode output from the

View File

@ -1003,12 +1003,15 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
// Generally inherit NoLineBreak from the current scope to nested scope.
// However, don't do this for non-empty nested blocks, dict literals and
// array literals as these follow different indentation rules.
const FormatToken *Previous = Current.getPreviousNonComment();
bool NoLineBreak =
Current.Children.empty() &&
!Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
(State.Stack.back().NoLineBreak ||
(Current.is(TT_TemplateOpener) &&
State.Stack.back().ContainsUnwrappedBuilder));
State.Stack.back().ContainsUnwrappedBuilder) ||
(Current.is(tok::l_brace) && !Newline && Previous &&
Previous->is(tok::comma)));
State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace,
AvoidBinPacking, NoLineBreak));
State.Stack.back().NestedBlockIndent = NestedBlockIndent;

View File

@ -286,12 +286,12 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
/// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
/// the specified properties.
static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign,
unsigned InlineWidth) {
static const char *getLockFreeValue(unsigned TypeWidth, unsigned InlineWidth) {
// Fully-aligned, power-of-2 sizes no larger than the inline
// width will be inlined as lock-free operations.
if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 &&
TypeWidth <= InlineWidth)
// Note: we do not need to check alignment since _Atomic(T) is always
// appropriately-aligned in clang.
if ((TypeWidth & (TypeWidth - 1)) == 0 && TypeWidth <= InlineWidth)
return "2"; // "always lock free"
// We cannot be certain what operations the lib calls might be
// able to implement as lock-free on future processors.
@ -881,7 +881,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
#define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \
Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
getLockFreeValue(TI.get##Type##Width(), \
TI.get##Type##Align(), \
InlineWidthBits));
DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
DEFINE_LOCK_FREE_MACRO(CHAR, Char);
@ -894,7 +893,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE",
getLockFreeValue(TI.getPointerWidth(0),
TI.getPointerAlign(0),
InlineWidthBits));
#undef DEFINE_LOCK_FREE_MACRO
}

View File

@ -7664,13 +7664,15 @@ vec_rlmi(vector unsigned long long __a, vector unsigned long long __b,
static __inline__ vector unsigned int __ATTRS_o_ai
vec_rlnm(vector unsigned int __a, vector unsigned int __b,
vector unsigned int __c) {
return __builtin_altivec_vrlwnm(__a, __b) & __c;
vector unsigned int OneByte = { 0x8, 0x8, 0x8, 0x8 };
return __builtin_altivec_vrlwnm(__a, ((__c << OneByte) | __b));
}
static __inline__ vector unsigned long long __ATTRS_o_ai
vec_rlnm(vector unsigned long long __a, vector unsigned long long __b,
vector unsigned long long __c) {
return __builtin_altivec_vrldnm(__a, __b) & __c;
vector unsigned long long OneByte = { 0x8, 0x8 };
return __builtin_altivec_vrldnm(__a, ((__c << OneByte) | __b));
}
#endif

View File

@ -46,10 +46,13 @@ public:
}
void handleDeclarator(const DeclaratorDecl *D,
const NamedDecl *Parent = nullptr) {
const NamedDecl *Parent = nullptr,
bool isIBType = false) {
if (!Parent) Parent = D;
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
Parent->getLexicalDeclContext(),
/*isBase=*/false, isIBType);
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
// Only index parameters in definitions, parameters in declarations are
@ -92,8 +95,11 @@ public:
if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic, Relations))
return false;
IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
for (const auto *I : D->parameters())
handleDeclarator(I, D);
bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
for (const auto *I : D->parameters()) {
handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
hasIBActionAndFirst = false;
}
if (D->isThisDeclarationADefinition()) {
const Stmt *Body = D->getBody();
@ -283,11 +289,12 @@ public:
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
const ObjCInterfaceDecl *C = D->getClassInterface();
if (C)
TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
SymbolRoleSet(), SymbolRelation{
(unsigned)SymbolRole::RelationExtendedBy, D
}));
if (!C)
return true;
TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
SymbolRelation{
(unsigned)SymbolRole::RelationExtendedBy, D
}));
SourceLocation CategoryLoc = D->getCategoryNameLoc();
if (!CategoryLoc.isValid())
CategoryLoc = D->getLocation();
@ -333,6 +340,9 @@ public:
handleObjCMethod(MD, D);
if (!IndexCtx.handleDecl(D))
return false;
if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
D->getLexicalDeclContext(), false, true);
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
return true;
}

View File

@ -152,10 +152,18 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
Info.Lang = SymbolLanguage::ObjC;
break;
case Decl::ObjCMethod:
if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
if (cast<ObjCMethodDecl>(D)->isInstanceMethod()) {
const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
Info.Kind = SymbolKind::InstanceMethod;
else
if (MD->isPropertyAccessor()) {
if (MD->param_size())
Info.SubKind = SymbolSubKind::AccessorSetter;
else
Info.SubKind = SymbolSubKind::AccessorGetter;
}
} else {
Info.Kind = SymbolKind::ClassMethod;
}
Info.Lang = SymbolLanguage::ObjC;
if (isUnitTest(cast<ObjCMethodDecl>(D)))
Info.Properties |= (unsigned)SymbolProperty::UnitTest;
@ -289,6 +297,8 @@ void index::applyForEachSymbolRole(SymbolRoleSet Roles,
APPLY_FOR_ROLE(RelationCalledBy);
APPLY_FOR_ROLE(RelationExtendedBy);
APPLY_FOR_ROLE(RelationAccessorOf);
APPLY_FOR_ROLE(RelationContainedBy);
APPLY_FOR_ROLE(RelationIBTypeOf);
#undef APPLY_FOR_ROLE
}
@ -317,6 +327,8 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
case SymbolRole::RelationExtendedBy: OS << "RelExt"; break;
case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
}
});
}
@ -375,6 +387,8 @@ StringRef index::getSymbolSubKindString(SymbolSubKind K) {
case SymbolSubKind::None: return "<none>";
case SymbolSubKind::CXXCopyConstructor: return "cxx-copy-ctor";
case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
case SymbolSubKind::AccessorGetter: return "acc-get";
case SymbolSubKind::AccessorSetter: return "acc-set";
}
llvm_unreachable("invalid symbol subkind");
}

View File

@ -26,12 +26,16 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
public:
TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
const DeclContext *DC, bool isBase)
const DeclContext *DC, bool isBase, bool isIBType)
: IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
if (IsBase) {
assert(Parent);
Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
}
if (isIBType) {
assert(Parent);
Relations.emplace_back((unsigned)SymbolRole::RelationIBTypeOf, Parent);
}
}
bool shouldWalkTypesOfTypeLocs() const { return false; }
@ -93,13 +97,13 @@ public:
bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
Parent, ParentDC, SymbolRoleSet());
Parent, ParentDC, SymbolRoleSet(), Relations);
}
bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
Parent, ParentDC, SymbolRoleSet());
Parent, ParentDC, SymbolRoleSet(), Relations);
}
return true;
}
@ -130,23 +134,25 @@ public:
void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
const NamedDecl *Parent,
const DeclContext *DC,
bool isBase) {
bool isBase,
bool isIBType) {
if (!TInfo || TInfo->getTypeLoc().isNull())
return;
indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase);
indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase, isIBType);
}
void IndexingContext::indexTypeLoc(TypeLoc TL,
const NamedDecl *Parent,
const DeclContext *DC,
bool isBase) {
bool isBase,
bool isIBType) {
if (TL.isNull())
return;
if (!DC)
DC = Parent->getLexicalDeclContext();
TypeIndexer(*this, Parent, DC, isBase).TraverseTypeLoc(TL);
TypeIndexer(*this, Parent, DC, isBase, isIBType).TraverseTypeLoc(TL);
}
void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,

View File

@ -312,9 +312,20 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
Roles |= Rel.Roles;
};
if (!IsRef && Parent && !cast<DeclContext>(Parent)->isFunctionOrMethod()) {
addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
if (Parent) {
if (IsRef) {
addRelation(SymbolRelation{
(unsigned)SymbolRole::RelationContainedBy,
Parent
});
} else if (!cast<DeclContext>(Parent)->isFunctionOrMethod()) {
addRelation(SymbolRelation{
(unsigned)SymbolRole::RelationChildOf,
Parent
});
}
}
for (auto &Rel : Relations) {
addRelation(SymbolRelation(Rel.Roles,
Rel.RelatedSymbol->getCanonicalDecl()));

View File

@ -85,11 +85,13 @@ public:
void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
const DeclContext *DC = nullptr,
bool isBase = false);
bool isBase = false,
bool isIBType = false);
void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
const DeclContext *DC = nullptr,
bool isBase = false);
bool isBase = false,
bool isIBType = false);
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
const NamedDecl *Parent,

View File

@ -1092,13 +1092,51 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
}
bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
const FileEntry *File,
bool isImport, Module *M) {
const FileEntry *File, bool isImport,
bool ModulesEnabled, Module *M) {
++NumIncluded; // Count # of attempted #includes.
// Get information about this file.
HeaderFileInfo &FileInfo = getFileInfo(File);
// FIXME: this is a workaround for the lack of proper modules-aware support
// for #import / #pragma once
auto TryEnterImported = [&](void) -> bool {
if (!ModulesEnabled)
return false;
// Modules with builtins are special; multiple modules use builtins as
// modular headers, example:
//
// module stddef { header "stddef.h" export * }
//
// After module map parsing, this expands to:
//
// module stddef {
// header "/path_to_builtin_dirs/stddef.h"
// textual "stddef.h"
// }
//
// It's common that libc++ and system modules will both define such
// submodules. Make sure cached results for a builtin header won't
// prevent other builtin modules to potentially enter the builtin header.
// Note that builtins are header guarded and the decision to actually
// enter them is postponed to the controlling macros logic below.
bool TryEnterHdr = false;
if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
ModuleMap::isBuiltinHeader(
llvm::sys::path::filename(File->getName()));
// Textual headers can be #imported from different modules. Since ObjC
// headers find in the wild might rely only on #import and do not contain
// controlling macros, be conservative and only try to enter textual headers
// if such macro is present.
if (!FileInfo.isModuleHeader &&
FileInfo.getControllingMacro(ExternalLookup))
TryEnterHdr = true;
return TryEnterHdr;
};
// If this is a #import directive, check that we have not already imported
// this header.
if (isImport) {
@ -1106,11 +1144,12 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
FileInfo.isImport = true;
// Has this already been #import'ed or #include'd?
if (FileInfo.NumIncludes) return false;
if (FileInfo.NumIncludes && !TryEnterImported())
return false;
} else {
// Otherwise, if this is a #include of a file that was previously #import'd
// or if this is the second #include of a #pragma once file, ignore it.
if (FileInfo.isImport)
if (FileInfo.isImport && !TryEnterImported())
return false;
}

View File

@ -144,7 +144,7 @@ static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
/// \brief Determine whether the given file name is the name of a builtin
/// header, supplied by Clang to replace, override, or augment existing system
/// headers.
static bool isBuiltinHeader(StringRef FileName) {
bool ModuleMap::isBuiltinHeader(StringRef FileName) {
return llvm::StringSwitch<bool>(FileName)
.Case("float.h", true)
.Case("iso646.h", true)
@ -165,7 +165,7 @@ ModuleMap::findKnownHeader(const FileEntry *File) {
HeadersMap::iterator Known = Headers.find(File);
if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
HeaderInfo.loadTopLevelSystemModules();
return Headers.find(File);
}
@ -446,9 +446,19 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
I = Known->second.begin(),
E = Known->second.end();
I != E; ++I) {
if (I->isAvailable() && (!RequestingModule ||
I->getModule()->isSubModuleOf(RequestingModule)))
if (I->isAvailable() &&
(!RequestingModule ||
I->getModule()->isSubModuleOf(RequestingModule))) {
// When no requesting module is available, the caller is looking if a
// header is part a module by only looking into the module map. This is
// done by warn_uncovered_module_header checks; don't consider textual
// headers part of it in this mode, otherwise we get misleading warnings
// that a umbrella header is not including a textual header.
if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
continue;
return false;
}
}
return true;
}
@ -1879,7 +1889,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// supplied by Clang. Find that builtin header.
if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
isBuiltinHeader(Header.FileName)) {
ModuleMap::isBuiltinHeader(Header.FileName)) {
SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
llvm::sys::path::append(BuiltinPathName, Header.FileName);
BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);

View File

@ -1999,6 +1999,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
bool SkipHeader = false;
if (ShouldEnter &&
!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
getLangOpts().Modules,
SuggestedModule.getModule())) {
ShouldEnter = false;
SkipHeader = true;

View File

@ -1591,7 +1591,7 @@ Parser::ParseSimpleDeclaration(unsigned Context,
DS.complete(TheDecl);
if (AnonRecord) {
Decl* decls[] = {AnonRecord, TheDecl};
return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
return Actions.BuildDeclaratorGroup(decls);
}
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
@ -2045,8 +2045,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
}
}
bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
// Parse declarator '=' initializer.
// If a '==' or '+=' is found, suggest a fixit to '='.
if (isTokenEqualOrEqualTypo()) {
@ -2106,7 +2104,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
Actions.ActOnInitializerError(ThisDecl);
} else
Actions.AddInitializerToDecl(ThisDecl, Init.get(),
/*DirectInit=*/false, TypeContainsAuto);
/*DirectInit=*/false);
}
} else if (Tok.is(tok::l_paren)) {
// Parse C++ direct initializer: '(' expression-list ')'
@ -2149,7 +2147,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
T.getCloseLocation(),
Exprs);
Actions.AddInitializerToDecl(ThisDecl, Initializer.get(),
/*DirectInit=*/true, TypeContainsAuto);
/*DirectInit=*/true);
}
} else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
(!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
@ -2171,11 +2169,10 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
if (Init.isInvalid()) {
Actions.ActOnInitializerError(ThisDecl);
} else
Actions.AddInitializerToDecl(ThisDecl, Init.get(),
/*DirectInit=*/true, TypeContainsAuto);
Actions.AddInitializerToDecl(ThisDecl, Init.get(), /*DirectInit=*/true);
} else {
Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
Actions.ActOnUninitializedDecl(ThisDecl);
}
Actions.FinalizeDeclaration(ThisDecl);

View File

@ -710,7 +710,7 @@ Parser::ParseUsingDeclaration(unsigned Context,
: "using declaration"))
SkipUntil(tok::semi);
return Actions.BuildDeclaratorGroup(DeclsInGroup, /*MayContainAuto*/false);
return Actions.BuildDeclaratorGroup(DeclsInGroup);
}
Decl *Parser::ParseAliasDeclarationAfterDeclarator(
@ -2539,7 +2539,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
DS.complete(TheDecl);
if (AnonRecord) {
Decl* decls[] = {AnonRecord, TheDecl};
return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
return Actions.BuildDeclaratorGroup(decls);
}
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
@ -2769,11 +2769,10 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (Init.isInvalid())
SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
else if (ThisDecl)
Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
DS.containsPlaceholderType());
Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid());
} else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static)
// No initializer.
Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType());
Actions.ActOnUninitializedDecl(ThisDecl);
if (ThisDecl) {
if (!ThisDecl->isInvalidDecl()) {
@ -3545,7 +3544,7 @@ Parser::tryParseExceptionSpecification(bool Delayed,
Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());
NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
} else {
NoexceptType = EST_None;
NoexceptType = EST_BasicNoexcept;
}
} else {
// There is no argument.

View File

@ -198,7 +198,7 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
// An expression is potentially evaluated unless it appears where an
// integral constant expression is required (see 5.19) [...].
// C++98 and C++11 have no such rule, but this is only a defect in C++98.
EnterExpressionEvaluationContext Unevaluated(Actions,
EnterExpressionEvaluationContext ConstantEvaluated(Actions,
Sema::ConstantEvaluated);
ExprResult LHS(ParseCastExpression(false, false, isTypeCast));

View File

@ -735,7 +735,7 @@ ExprResult Parser::TryParseLambdaExpression() {
/// sometimes skip the initializers for init-captures and not fully
/// populate \p Intro. This flag will be set to \c true if we do so.
/// \return A DiagnosticID if it hit something unexpected. The location for
/// for the diagnostic is that of the current token.
/// the diagnostic is that of the current token.
Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
bool *SkippedInits) {
typedef Optional<unsigned> DiagResult;
@ -1818,8 +1818,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
}
if (!InitExpr.isInvalid())
Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization,
DS.containsPlaceholderType());
Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization);
else
Actions.ActOnInitializerError(DeclOut);

View File

@ -119,6 +119,7 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
{ OMPD_target, OMPD_teams, OMPD_target_teams },
{ OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute },
{ OMPD_target_teams_distribute, OMPD_parallel, OMPD_target_teams_distribute_parallel },
{ OMPD_target_teams_distribute, OMPD_simd, OMPD_target_teams_distribute_simd },
{ OMPD_target_teams_distribute_parallel, OMPD_for, OMPD_target_teams_distribute_parallel_for },
{ OMPD_target_teams_distribute_parallel_for, OMPD_simd, OMPD_target_teams_distribute_parallel_for_simd }
};
@ -760,6 +761,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_target_teams_distribute:
case OMPD_target_teams_distribute_parallel_for:
case OMPD_target_teams_distribute_parallel_for_simd:
case OMPD_target_teams_distribute_simd:
Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind);
break;
@ -799,7 +801,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
/// 'teams distribute parallel for' | 'target teams' |
/// 'target teams distribute' |
/// 'target teams distribute parallel for' |
/// 'target teams distribute parallel for simd' {clause}
/// 'target teams distribute parallel for simd' |
/// 'target teams distribute simd' {clause}
/// annot_pragma_openmp_end
///
StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
@ -916,7 +919,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_target_teams:
case OMPD_target_teams_distribute:
case OMPD_target_teams_distribute_parallel_for:
case OMPD_target_teams_distribute_parallel_for_simd: {
case OMPD_target_teams_distribute_parallel_for_simd:
case OMPD_target_teams_distribute_simd: {
ConsumeToken();
// Parse directive name of the 'critical' directive if any.
if (DKind == OMPD_critical) {

View File

@ -938,7 +938,7 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
Actions.setCurrentOpenCLExtensionForDecl(TheDecl);
if (AnonRecord) {
Decl* decls[] = {AnonRecord, TheDecl};
return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
return Actions.BuildDeclaratorGroup(decls);
}
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
@ -1472,8 +1472,7 @@ Parser::TryAnnotateName(bool IsAddressOfOperand,
return ANK_Error;
if (Tok.isNot(tok::identifier) || SS.isInvalid()) {
if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, false, SS,
!WasScopeAnnotation))
if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation))
return ANK_Error;
return ANK_Unresolved;
}
@ -1486,8 +1485,7 @@ Parser::TryAnnotateName(bool IsAddressOfOperand,
if (isTentativelyDeclared(Name)) {
// Identifier has been tentatively declared, and thus cannot be resolved as
// an expression. Fall back to annotating it as a type.
if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, false, SS,
!WasScopeAnnotation))
if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation))
return ANK_Error;
return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;
}
@ -1625,7 +1623,7 @@ bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
///
/// Note that this routine emits an error if you call it with ::new or ::delete
/// as the current tokens, so only call it in contexts where these are invalid.
bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
bool Parser::TryAnnotateTypeOrScopeToken() {
assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||
Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||
@ -1642,7 +1640,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) {
Token TypedefToken;
PP.Lex(TypedefToken);
bool Result = TryAnnotateTypeOrScopeToken(EnteringContext, NeedType);
bool Result = TryAnnotateTypeOrScopeToken();
PP.EnterToken(Tok);
Tok = TypedefToken;
if (!Result)
@ -1667,8 +1665,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
Tok.is(tok::annot_decltype)) {
// Attempt to recover by skipping the invalid 'typename'
if (Tok.is(tok::annot_decltype) ||
(!TryAnnotateTypeOrScopeToken(EnteringContext, NeedType) &&
Tok.isAnnotation())) {
(!TryAnnotateTypeOrScopeToken() && Tok.isAnnotation())) {
unsigned DiagID = diag::err_expected_qualified_after_typename;
// MS compatibility: MSVC permits using known types with typename.
// e.g. "typedef typename T* pointer_type"
@ -1728,33 +1725,24 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
CXXScopeSpec SS;
if (getLangOpts().CPlusPlus)
if (ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext))
if (ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext*/false))
return true;
return TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, NeedType,
SS, !WasScopeAnnotation);
return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation);
}
/// \brief Try to annotate a type or scope token, having already parsed an
/// optional scope specifier. \p IsNewScope should be \c true unless the scope
/// specifier was extracted from an existing tok::annot_cxxscope annotation.
bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
bool NeedType,
CXXScopeSpec &SS,
bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
bool IsNewScope) {
if (Tok.is(tok::identifier)) {
IdentifierInfo *CorrectedII = nullptr;
// Determine whether the identifier is a type name.
if (ParsedType Ty = Actions.getTypeName(
*Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS,
false, NextToken().is(tok::period), nullptr,
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo*/ true,
NeedType ? &CorrectedII : nullptr)) {
// A FixIt was applied as a result of typo correction
if (CorrectedII)
Tok.setIdentifierInfo(CorrectedII);
/*NonTrivialTypeSourceInfo*/ true)) {
SourceLocation BeginLoc = Tok.getLocation();
if (SS.isNotEmpty()) // it was a C++ qualified type name.
BeginLoc = SS.getBeginLoc();
@ -1803,11 +1791,11 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
UnqualifiedId TemplateName;
TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
bool MemberOfUnknownSpecialization;
if (TemplateNameKind TNK =
Actions.isTemplateName(getCurScope(), SS,
/*hasTemplateKeyword=*/false, TemplateName,
/*ObjectType=*/nullptr, EnteringContext,
Template, MemberOfUnknownSpecialization)) {
if (TemplateNameKind TNK = Actions.isTemplateName(
getCurScope(), SS,
/*hasTemplateKeyword=*/false, TemplateName,
/*ObjectType=*/nullptr, /*EnteringContext*/false, Template,
MemberOfUnknownSpecialization)) {
// Consume the identifier.
ConsumeToken();
if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),

View File

@ -56,6 +56,8 @@ using namespace clang;
namespace {
class UnreachableCodeHandler : public reachable_code::Callback {
Sema &S;
SourceRange PreviousSilenceableCondVal;
public:
UnreachableCodeHandler(Sema &s) : S(s) {}
@ -64,6 +66,14 @@ namespace {
SourceRange SilenceableCondVal,
SourceRange R1,
SourceRange R2) override {
// Avoid reporting multiple unreachable code diagnostics that are
// triggered by the same conditional value.
if (PreviousSilenceableCondVal.isValid() &&
SilenceableCondVal.isValid() &&
PreviousSilenceableCondVal == SilenceableCondVal)
return;
PreviousSilenceableCondVal = SilenceableCondVal;
unsigned diag = diag::warn_unreachable;
switch (UK) {
case reachable_code::UK_Break:

View File

@ -187,7 +187,7 @@ static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc,
S.Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
S.CheckVariableDeclarationType(ScopeInfo->CoroutinePromise);
if (!ScopeInfo->CoroutinePromise->isInvalidDecl())
S.ActOnUninitializedDecl(ScopeInfo->CoroutinePromise, false);
S.ActOnUninitializedDecl(ScopeInfo->CoroutinePromise);
}
return ScopeInfo;
@ -578,17 +578,6 @@ void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
isa<CoyieldExpr>(First) ? 1 : 2);
}
bool AnyCoawaits = false;
bool AnyCoyields = false;
for (auto *CoroutineStmt : Fn->CoroutineStmts) {
AnyCoawaits |= isa<CoawaitExpr>(CoroutineStmt);
AnyCoyields |= isa<CoyieldExpr>(CoroutineStmt);
}
if (!AnyCoawaits && !AnyCoyields)
Diag(Fn->CoroutineStmts.front()->getLocStart(),
diag::ext_coroutine_without_co_await_co_yield);
SourceLocation Loc = FD->getLocation();
// Form a declaration statement for the promise declaration, so that AST

View File

@ -1044,7 +1044,8 @@ Corrected:
}
// We can have a type template here if we're classifying a template argument.
if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl))
if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl) &&
!isa<VarTemplateDecl>(FirstDecl))
return NameClassification::TypeTemplate(
TemplateName(cast<TemplateDecl>(FirstDecl)));
@ -4503,7 +4504,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// trivial in almost all cases, except if a union member has an in-class
// initializer:
// union { int n = 0; };
ActOnUninitializedDecl(Anon, /*TypeMayContainAuto=*/false);
ActOnUninitializedDecl(Anon);
}
Anon->setImplicit();
@ -6425,9 +6426,10 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
// Diagnose shadowed variables before filtering for scope.
if (D.getCXXScopeSpec().isEmpty())
CheckShadow(S, NewVD, Previous);
// Find the shadowed declaration before filtering for scope.
NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
? getShadowedDeclaration(NewVD, Previous)
: nullptr;
// Don't consider existing declarations that are in a different
// scope and are out-of-semantic-context declarations (if the new
@ -6522,6 +6524,10 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
// Diagnose shadowed variables iff this isn't a redeclaration.
if (ShadowedDecl && !D.isRedeclaration())
CheckShadow(NewVD, ShadowedDecl, Previous);
ProcessPragmaWeak(S, NewVD);
// If this is the first declaration of an extern C variable, update
@ -6595,34 +6601,41 @@ static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI,
return SourceLocation();
}
/// \brief Return the declaration shadowed by the given variable \p D, or null
/// if it doesn't shadow any declaration or shadowing warnings are disabled.
NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
const LookupResult &R) {
// Return if warning is ignored.
if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
return nullptr;
// Don't diagnose declarations at file scope.
if (D->hasGlobalStorage())
return nullptr;
// Only diagnose if we're shadowing an unambiguous field or variable.
if (R.getResultKind() != LookupResult::Found)
return nullptr;
NamedDecl *ShadowedDecl = R.getFoundDecl();
return isa<VarDecl>(ShadowedDecl) || isa<FieldDecl>(ShadowedDecl)
? ShadowedDecl
: nullptr;
}
/// \brief Diagnose variable or built-in function shadowing. Implements
/// -Wshadow.
///
/// This method is called whenever a VarDecl is added to a "useful"
/// scope.
///
/// \param S the scope in which the shadowing name is being declared
/// \param ShadowedDecl the declaration that is shadowed by the given variable
/// \param R the lookup of the name
///
void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
// Return if warning is ignored.
if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
return;
// Don't diagnose declarations at file scope.
if (D->hasGlobalStorage())
return;
void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
const LookupResult &R) {
DeclContext *NewDC = D->getDeclContext();
// Only diagnose if we're shadowing an unambiguous field or variable.
if (R.getResultKind() != LookupResult::Found)
return;
NamedDecl* ShadowedDecl = R.getFoundDecl();
if (!isa<VarDecl>(ShadowedDecl) && !isa<FieldDecl>(ShadowedDecl))
return;
if (FieldDecl *FD = dyn_cast<FieldDecl>(ShadowedDecl)) {
// Fields are not shadowed by variables in C++ static methods.
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewDC))
@ -6732,7 +6745,8 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) {
LookupResult R(*this, D->getDeclName(), D->getLocation(),
Sema::LookupOrdinaryName, Sema::ForRedeclaration);
LookupName(R, S);
CheckShadow(S, D, R);
if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R))
CheckShadow(D, ShadowedDecl, R);
}
/// Check if 'E', which is an expression that is about to be modified, refers
@ -9782,8 +9796,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
/// AddInitializerToDecl - Adds the initializer Init to the
/// declaration dcl. If DirectInit is true, this is C++ direct
/// initialization rather than copy initialization.
void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
bool DirectInit, bool TypeMayContainAuto) {
void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// If there is no declaration, there was an error parsing it. Just ignore
// the initializer.
if (!RealDecl || RealDecl->isInvalidDecl()) {
@ -9808,7 +9821,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
}
// C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) {
if (VDecl->getType()->isUndeducedType()) {
// Attempt typo correction early so that the type of the init expression can
// be deduced based on the chosen correction if the original init contains a
// TypoExpr.
@ -10280,8 +10293,7 @@ bool Sema::canInitializeWithParenthesizedList(QualType TargetType) {
TargetType->getContainedAutoType();
}
void Sema::ActOnUninitializedDecl(Decl *RealDecl,
bool TypeMayContainAuto) {
void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
// If there is no declaration, there was an error parsing it. Just ignore it.
if (!RealDecl)
return;
@ -10297,7 +10309,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
}
// C++11 [dcl.spec.auto]p3
if (TypeMayContainAuto && Type->getContainedAutoType()) {
if (Type->isUndeducedType()) {
Diag(Var->getLocation(), diag::err_auto_var_requires_init)
<< Var->getDeclName() << Type;
Var->setInvalidDecl();
@ -11081,32 +11093,32 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
}
}
return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType());
return BuildDeclaratorGroup(Decls);
}
/// BuildDeclaratorGroup - convert a list of declarations into a declaration
/// group, performing any necessary semantic checking.
Sema::DeclGroupPtrTy
Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
bool TypeMayContainAuto) {
// C++0x [dcl.spec.auto]p7:
// If the type deduced for the template parameter U is not the same in each
Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group) {
// C++14 [dcl.spec.auto]p7: (DR1347)
// If the type that replaces the placeholder type is not the same in each
// deduction, the program is ill-formed.
// FIXME: When initializer-list support is added, a distinction is needed
// between the deduced type U and the deduced type which 'auto' stands for.
// auto a = 0, b = { 1, 2, 3 };
// is legal because the deduced type U is 'int' in both cases.
if (TypeMayContainAuto && Group.size() > 1) {
if (Group.size() > 1) {
QualType Deduced;
CanQualType DeducedCanon;
VarDecl *DeducedDecl = nullptr;
for (unsigned i = 0, e = Group.size(); i != e; ++i) {
if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) {
AutoType *AT = D->getType()->getContainedAutoType();
// FIXME: DR1265: if we have a function pointer declaration, we can have
// an 'auto' from a trailing return type. In that case, the return type
// must match the various other uses of 'auto'.
if (!AT)
continue;
// Don't reissue diagnostics when instantiating a template.
if (AT && D->isInvalidDecl())
if (D->isInvalidDecl())
break;
QualType U = AT ? AT->getDeducedType() : QualType();
QualType U = AT->getDeducedType();
if (!U.isNull()) {
CanQualType UCanon = Context.getCanonicalType(U);
if (Deduced.isNull()) {

View File

@ -1712,7 +1712,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
DeclsInGroup.push_back(PDecl);
}
return BuildDeclaratorGroup(DeclsInGroup, false);
return BuildDeclaratorGroup(DeclsInGroup);
}
Decl *Sema::
@ -2019,7 +2019,7 @@ Sema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) {
DeclsInGroup.push_back(ObjCImpDecl);
return BuildDeclaratorGroup(DeclsInGroup, false);
return BuildDeclaratorGroup(DeclsInGroup);
}
void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@ -3043,7 +3043,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
DeclsInGroup.push_back(IDecl);
}
return BuildDeclaratorGroup(DeclsInGroup, false);
return BuildDeclaratorGroup(DeclsInGroup);
}
static bool tryMatchRecordTypes(ASTContext &Context,

View File

@ -1504,14 +1504,12 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, SourceRange TypeIdParens,
Declarator &D, Expr *Initializer) {
bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
Expr *ArraySize = nullptr;
// If the specified type is an array, unwrap it and save the expression.
if (D.getNumTypeObjects() > 0 &&
D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
DeclaratorChunk &Chunk = D.getTypeObject(0);
if (TypeContainsAuto)
DeclaratorChunk &Chunk = D.getTypeObject(0);
if (D.getDeclSpec().containsPlaceholderType())
return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
<< D.getSourceRange());
if (Chunk.Arr.hasStatic)
@ -1588,8 +1586,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
TInfo,
ArraySize,
DirectInitRange,
Initializer,
TypeContainsAuto);
Initializer);
}
static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
@ -1621,8 +1618,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
TypeSourceInfo *AllocTypeInfo,
Expr *ArraySize,
SourceRange DirectInitRange,
Expr *Initializer,
bool TypeMayContainAuto) {
Expr *Initializer) {
SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
SourceLocation StartLoc = Range.getBegin();
@ -1648,7 +1644,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
}
// C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && AllocType->isUndeducedType()) {
if (AllocType->isUndeducedType()) {
if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
<< AllocType << TypeRange);

View File

@ -1089,7 +1089,7 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
auto *VDPrivate = buildVarDecl(
*this, DE->getExprLoc(), Type.getUnqualifiedType(),
VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
ActOnUninitializedDecl(VDPrivate);
if (VDPrivate->isInvalidDecl())
continue;
PrivateCopies.push_back(buildDeclRefExpr(
@ -1701,7 +1701,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_teams_distribute_parallel_for:
case OMPD_target_teams_distribute:
case OMPD_target_teams_distribute_parallel_for:
case OMPD_target_teams_distribute_parallel_for_simd: {
case OMPD_target_teams_distribute_parallel_for_simd:
case OMPD_target_teams_distribute_simd: {
QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
QualType KmpInt32PtrTy =
Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
@ -1761,8 +1762,7 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
if (!WithInit)
CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
S.CurContext->addHiddenDecl(CED);
S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false,
/*TypeMayContainAuto=*/true);
S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
return CED;
}
@ -2446,6 +2446,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
AllowedNameModifiers.push_back(OMPD_target);
AllowedNameModifiers.push_back(OMPD_parallel);
break;
case OMPD_target_teams_distribute_simd:
Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
AllowedNameModifiers.push_back(OMPD_target);
break;
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_threadprivate:
@ -3970,33 +3975,32 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// Lower bound variable, initialized with zero.
VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
SemaRef.AddInitializerToDecl(
LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
SemaRef.AddInitializerToDecl(LBDecl,
SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
/*DirectInit*/ false);
// Upper bound variable, initialized with last iteration number.
VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
/*DirectInit*/ false,
/*TypeMayContainAuto*/ false);
/*DirectInit*/ false);
// A 32-bit variable-flag where runtime returns 1 for the last iteration.
// This will be used to implement clause 'lastprivate'.
QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
SemaRef.AddInitializerToDecl(
ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
SemaRef.AddInitializerToDecl(ILDecl,
SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
/*DirectInit*/ false);
// Stride variable returned by runtime (we initialize it to 1 by default).
VarDecl *STDecl =
buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
SemaRef.AddInitializerToDecl(
STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
SemaRef.AddInitializerToDecl(STDecl,
SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
/*DirectInit*/ false);
// Build expression: UB = min(UB, LastIteration)
// It is necessary for CodeGen of directives with static scheduling.
@ -6428,6 +6432,39 @@ StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
}
StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
if (!AStmt)
return StmtError();
auto *CS = cast<CapturedStmt>(AStmt);
// 1.2.2 OpenMP Language Terminology
// Structured block - An executable statement with a single entry at the
// top and a single exit at the bottom.
// The point of exit cannot be a branch out of the structured block.
// longjmp() and throw() must not violate the entry/exit criteria.
CS->getCapturedDecl()->setNothrow();
OMPLoopDirective::HelperExprs B;
// In presence of clause 'collapse' with number of loops, it will
// define the nested loops number.
auto NestedLoopCount = CheckOpenMPLoop(
OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
VarsWithImplicitDSA, B);
if (NestedLoopCount == 0)
return StmtError();
assert((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built");
getCurFunction()->setHasBranchProtectedScope();
return OMPTargetTeamsDistributeSimdDirective::Create(
Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
}
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@ -7448,10 +7485,13 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
// A list item cannot appear in both a map clause and a data-sharing
// attribute clause on the same construct
if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
CurrDir == OMPD_target_teams ||
CurrDir == OMPD_target_teams ||
CurrDir == OMPD_target_teams_distribute ||
CurrDir == OMPD_target_teams_distribute_parallel_for ||
CurrDir == OMPD_target_teams_distribute_parallel_for_simd) {
CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
CurrDir == OMPD_target_teams_distribute_simd ||
CurrDir == OMPD_target_parallel_for_simd ||
CurrDir == OMPD_target_parallel_for) {
OpenMPClauseKind ConflictKind;
if (DSAStack->checkMappableExprComponentListsForDecl(
VD, /*CurrentRegionOnly=*/true,
@ -7481,7 +7521,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
Type = Type.getUnqualifiedType();
auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
D->hasAttrs() ? &D->getAttrs() : nullptr);
ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
ActOnUninitializedDecl(VDPrivate);
if (VDPrivate->isInvalidDecl())
continue;
auto VDPrivateRefExpr = buildDeclRefExpr(
@ -7709,10 +7749,13 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
// A list item cannot appear in both a map clause and a data-sharing
// attribute clause on the same construct
if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
CurrDir == OMPD_target_teams ||
CurrDir == OMPD_target_teams ||
CurrDir == OMPD_target_teams_distribute ||
CurrDir == OMPD_target_teams_distribute_parallel_for ||
CurrDir == OMPD_target_teams_distribute_parallel_for_simd) {
CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
CurrDir == OMPD_target_teams_distribute_simd ||
CurrDir == OMPD_target_parallel_for_simd ||
CurrDir == OMPD_target_parallel_for) {
OpenMPClauseKind ConflictKind;
if (DSAStack->checkMappableExprComponentListsForDecl(
VD, /*CurrentRegionOnly=*/true,
@ -7784,7 +7827,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
RefExpr->getExprLoc());
AddInitializerToDecl(VDPrivate,
DefaultLvalueConversion(VDInitRefExpr).get(),
/*DirectInit=*/false, /*TypeMayContainAuto=*/false);
/*DirectInit=*/false);
}
if (VDPrivate->isInvalidDecl()) {
if (IsImplicitClause) {
@ -8634,10 +8677,9 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
}
}
if (Init && DeclareReductionRef.isUnset()) {
AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false,
/*TypeMayContainAuto=*/false);
AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
} else if (!Init)
ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false);
ActOnUninitializedDecl(RHSVD);
if (RHSVD->isInvalidDecl())
continue;
if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
@ -8886,7 +8928,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
else
InitExpr = VD ? SimpleRefExpr : Ref;
AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
/*DirectInit=*/false, /*TypeMayContainAuto=*/false);
/*DirectInit=*/false);
auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
@ -10231,7 +10273,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
DKind == OMPD_target_teams_distribute ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd) && VD) {
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd) && VD) {
auto DVar = DSAS->getTopDSA(VD, false);
if (isOpenMPPrivate(DVar.CKind)) {
SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
@ -10963,7 +11006,7 @@ OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
RefExpr->getExprLoc());
AddInitializerToDecl(VDPrivate,
DefaultLvalueConversion(VDInitRefExpr).get(),
/*DirectInit=*/false, /*TypeMayContainAuto=*/false);
/*DirectInit=*/false);
// If required, build a capture to implement the privatization initialized
// with the current list item value.

View File

@ -6596,7 +6596,9 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
Candidate.Function = MethodTmpl->getTemplatedDecl();
Candidate.Viable = false;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.IgnoreObjectArgument =
cast<CXXMethodDecl>(Candidate.Function)->isStatic() ||
ObjectType.isNull();
Candidate.ExplicitCallArguments = Args.size();
if (Result == TDK_NonDependentConversionFailure)
Candidate.FailureKind = ovl_fail_bad_conversion;
@ -6658,7 +6660,11 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
Candidate.Function = FunctionTemplate->getTemplatedDecl();
Candidate.Viable = false;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
// Ignore the object argument if there is one, since we don't have an object
// type.
Candidate.IgnoreObjectArgument =
isa<CXXMethodDecl>(Candidate.Function) &&
!isa<CXXConstructorDecl>(Candidate.Function);
Candidate.ExplicitCallArguments = Args.size();
if (Result == TDK_NonDependentConversionFailure)
Candidate.FailureKind = ovl_fail_bad_conversion;
@ -10490,56 +10496,42 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
// operation somehow.
bool SuppressUserConversions = false;
const FunctionProtoType *Proto;
unsigned ArgIdx = 0;
unsigned ConvIdx = 0;
ArrayRef<QualType> ParamTypes;
if (Cand->IsSurrogate) {
QualType ConvType
= Cand->Surrogate->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
ConvType = ConvPtrType->getPointeeType();
Proto = ConvType->getAs<FunctionProtoType>();
ArgIdx = 1;
ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes();
// Conversion 0 is 'this', which doesn't have a corresponding argument.
ConvIdx = 1;
} else if (Cand->Function) {
Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
ParamTypes =
Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes();
if (isa<CXXMethodDecl>(Cand->Function) &&
!isa<CXXConstructorDecl>(Cand->Function))
ArgIdx = 1;
} else {
// Builtin binary operator with a bad first conversion.
assert(ConvCount <= 3);
for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
ConvIdx != ConvCount; ++ConvIdx) {
if (Cand->Conversions[ConvIdx].isInitialized())
continue;
if (Cand->BuiltinTypes.ParamTypes[ConvIdx]->isDependentType())
Cand->Conversions[ConvIdx].setAsIdentityConversion(
Args[ConvIdx]->getType());
else
Cand->Conversions[ConvIdx] = TryCopyInitialization(
S, Args[ConvIdx], Cand->BuiltinTypes.ParamTypes[ConvIdx],
SuppressUserConversions,
/*InOverloadResolution*/ true,
/*AllowObjCWritebackConversion=*/
S.getLangOpts().ObjCAutoRefCount);
// FIXME: If the conversion is bad, try to fix it.
!isa<CXXConstructorDecl>(Cand->Function)) {
// Conversion 0 is 'this', which doesn't have a corresponding argument.
ConvIdx = 1;
}
return;
} else {
// Builtin operator.
assert(ConvCount <= 3);
ParamTypes = Cand->BuiltinTypes.ParamTypes;
}
// Fill in the rest of the conversions.
unsigned NumParams = Proto->getNumParams();
for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
if (Cand->Conversions[ConvIdx].isInitialized()) {
// Found the bad conversion.
} else if (ArgIdx < NumParams) {
if (Proto->getParamType(ArgIdx)->isDependentType())
// We've already checked this conversion.
} else if (ArgIdx < ParamTypes.size()) {
if (ParamTypes[ArgIdx]->isDependentType())
Cand->Conversions[ConvIdx].setAsIdentityConversion(
Args[ArgIdx]->getType());
else {
Cand->Conversions[ConvIdx] =
TryCopyInitialization(S, Args[ArgIdx], Proto->getParamType(ArgIdx),
TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx],
SuppressUserConversions,
/*InOverloadResolution=*/true,
/*AllowObjCWritebackConversion=*/

View File

@ -1881,8 +1881,7 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
SemaRef.inferObjCARCLifetime(Decl))
Decl->setInvalidDecl();
SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false,
/*TypeMayContainAuto=*/false);
SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false);
SemaRef.FinalizeDeclaration(Decl);
SemaRef.CurContext->addHiddenDecl(Decl);
return false;
@ -2005,8 +2004,7 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc,
// Claim the type doesn't contain auto: we've already done the checking.
DeclGroupPtrTy RangeGroup =
BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
/*TypeMayContainAuto=*/ false);
BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1));
StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
if (RangeDecl.isInvalid()) {
LoopVar->setInvalidDecl();
@ -2408,8 +2406,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc,
// Attach *__begin as initializer for VD. Don't touch it if we're just
// trying to determine whether this would be a valid range.
if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) {
AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false,
/*TypeMayContainAuto=*/true);
AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false);
if (LoopVar->isInvalidDecl())
NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
}

View File

@ -1224,9 +1224,17 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
}
}
// If this is a templated friend in a dependent context we should not put it
// on the redecl chain. In some cases, the templated friend can be the most
// recent declaration tricking the template instantiator to make substitutions
// there.
// FIXME: Figure out how to combine with shouldLinkDependentDeclWithPrevious
bool ShouldAddRedecl
= !(TUK == TUK_Friend && CurContext->isDependentContext());
CXXRecordDecl *NewClass =
CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
PrevClassTemplate?
PrevClassTemplate && ShouldAddRedecl ?
PrevClassTemplate->getTemplatedDecl() : nullptr,
/*DelayTypeCreation=*/true);
SetNestedNameSpecifier(NewClass, SS);
@ -1245,7 +1253,11 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
ClassTemplateDecl *NewTemplate
= ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
DeclarationName(Name), TemplateParams,
NewClass, PrevClassTemplate);
NewClass);
if (ShouldAddRedecl)
NewTemplate->setPreviousDecl(PrevClassTemplate);
NewClass->setDescribedClassTemplate(NewTemplate);
if (ModulePrivateLoc.isValid())
@ -1653,6 +1665,7 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
typedef RecursiveASTVisitor<DependencyChecker> super;
unsigned Depth;
bool FindLessThanDepth;
// Whether we're looking for a use of a template parameter that makes the
// overall construct type-dependent / a dependent type. This is strictly
@ -1663,25 +1676,16 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
bool Match;
SourceLocation MatchLoc;
DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent)
: Depth(Depth), IgnoreNonTypeDependent(IgnoreNonTypeDependent),
Match(false) {}
DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent,
bool FindLessThanDepth = false)
: Depth(Depth), FindLessThanDepth(FindLessThanDepth),
IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) {}
DependencyChecker(TemplateParameterList *Params, bool IgnoreNonTypeDependent)
: IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) {
NamedDecl *ND = Params->getParam(0);
if (TemplateTypeParmDecl *PD = dyn_cast<TemplateTypeParmDecl>(ND)) {
Depth = PD->getDepth();
} else if (NonTypeTemplateParmDecl *PD =
dyn_cast<NonTypeTemplateParmDecl>(ND)) {
Depth = PD->getDepth();
} else {
Depth = cast<TemplateTemplateParmDecl>(ND)->getDepth();
}
}
: DependencyChecker(Params->getDepth(), IgnoreNonTypeDependent) {}
bool Matches(unsigned ParmDepth, SourceLocation Loc = SourceLocation()) {
if (ParmDepth >= Depth) {
if (FindLessThanDepth ^ (ParmDepth >= Depth)) {
Match = true;
MatchLoc = Loc;
return true;
@ -2336,15 +2340,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// A<T, T> have identical types when A is declared as:
//
// template<typename T, typename U = T> struct A;
TemplateName CanonName = Context.getCanonicalTemplateName(Name);
CanonType = Context.getTemplateSpecializationType(CanonName,
Converted);
// FIXME: CanonType is not actually the canonical type, and unfortunately
// it is a TemplateSpecializationType that we will never use again.
// In the future, we need to teach getTemplateSpecializationType to only
// build the canonical type and return that to us.
CanonType = Context.getCanonicalType(CanonType);
CanonType = Context.getCanonicalTemplateSpecializationType(Name, Converted);
// This might work out to be a current instantiation, in which
// case the canonical type needs to be the InjectedClassNameType.
@ -3452,7 +3448,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
TemplateTypeParmDecl *Param,
SmallVectorImpl<TemplateArgument> &Converted) {
SmallVectorImpl<TemplateArgument> &Converted) {
TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
// If the argument type is dependent, instantiate it now based
@ -5838,6 +5834,15 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
return E;
}
static bool isDependentOnOuter(NonTypeTemplateParmDecl *NTTP) {
if (NTTP->getDepth() == 0 || !NTTP->getType()->isDependentType())
return false;
DependencyChecker Checker(NTTP->getDepth(), /*IgnoreNonTypeDependent*/ false,
/*FindLessThanDepth*/ true);
Checker.TraverseType(NTTP->getType());
return Checker.Match;
}
/// \brief Match two template parameters within template parameter lists.
static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old,
bool Complain,
@ -5894,11 +5899,10 @@ static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old,
// If we are matching a template template argument to a template
// template parameter and one of the non-type template parameter types
// is dependent, then we must wait until template instantiation time
// to actually compare the arguments.
// is dependent on an outer template's parameter, then we must wait until
// template instantiation time to actually compare the arguments.
if (Kind == Sema::TPL_TemplateTemplateArgumentMatch &&
(OldNTTP->getType()->isDependentType() ||
NewNTTP->getType()->isDependentType()))
(isDependentOnOuter(OldNTTP) || isDependentOnOuter(NewNTTP)))
return true;
if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) {
@ -7785,6 +7789,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
Specialization->setTemplateKeywordLoc(TemplateLoc);
Specialization->setBraceRange(SourceRange());
bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>();
if (Attr)
ProcessDeclAttributeList(S, Specialization, Attr);
@ -7847,8 +7852,9 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Fix a TSK_ImplicitInstantiation followed by a
// TSK_ExplicitInstantiationDefinition
if (Old_TSK == TSK_ImplicitInstantiation &&
Specialization->hasAttr<DLLExportAttr>() &&
bool NewlyDLLExported =
!PreviouslyDLLExported && Specialization->hasAttr<DLLExportAttr>();
if (Old_TSK == TSK_ImplicitInstantiation && NewlyDLLExported &&
(Context.getTargetInfo().getCXXABI().isMicrosoft() ||
Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
// In the MS ABI, an explicit instantiation definition can add a dll

View File

@ -2264,9 +2264,6 @@ bool Sema::InstantiateInClassInitializer(
if (auto *L = getASTMutationListener())
L->DefaultMemberInitializerInstantiated(Instantiation);
// Exit the scope of this instantiation.
SavedContext.pop();
// Return true if the in-class initializer is still missing.
return !Instantiation->getInClassInitializer();
}

View File

@ -1219,8 +1219,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
ClassTemplateDecl *Inst
= ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(),
D->getIdentifier(), InstParams, RecordInst,
PrevClassTemplate);
D->getIdentifier(), InstParams, RecordInst);
assert(!(isFriend && Owner->isDependentContext()));
Inst->setPreviousDecl(PrevClassTemplate);
RecordInst->setDescribedClassTemplate(Inst);
if (isFriend) {
@ -4085,7 +4087,6 @@ void Sema::InstantiateVariableInitializer(
}
if (!Init.isInvalid()) {
bool TypeMayContainAuto = true;
Expr *InitExpr = Init.get();
if (Var->hasAttr<DLLImportAttr>() &&
@ -4094,9 +4095,9 @@ void Sema::InstantiateVariableInitializer(
// Do not dynamically initialize dllimport variables.
} else if (InitExpr) {
bool DirectInit = OldVar->isDirectInit();
AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto);
AddInitializerToDecl(Var, InitExpr, DirectInit);
} else
ActOnUninitializedDecl(Var, TypeMayContainAuto);
ActOnUninitializedDecl(Var);
} else {
// FIXME: Not too happy about invalidating the declaration
// because of a bogus initializer.
@ -4119,7 +4120,7 @@ void Sema::InstantiateVariableInitializer(
if (Var->isCXXForRangeDecl())
return;
ActOnUninitializedDecl(Var, false);
ActOnUninitializedDecl(Var);
}
}

View File

@ -5263,7 +5263,7 @@ namespace {
ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
TL.setParam(tpi++, Param);
}
// FIXME: exception specs
TL.setExceptionSpecRange(FTI.getExceptionSpecRange());
}
void VisitParenTypeLoc(ParenTypeLoc TL) {
assert(Chunk.Kind == DeclaratorChunk::Paren);

View File

@ -5023,6 +5023,7 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType(
NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
NewTL.setLParenLoc(TL.getLParenLoc());
NewTL.setRParenLoc(TL.getRParenLoc());
NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
NewTL.setParam(i, ParamDecls[i]);
@ -7779,6 +7780,18 @@ StmtResult TreeTransform<Derived>::
return Res;
}
template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
OMPTargetTeamsDistributeSimdDirective *D) {
DeclarationNameInfo DirName;
getDerived().getSema().StartOpenMPDSABlock(
OMPD_target_teams_distribute_simd, DirName, nullptr, D->getLocStart());
auto Res = getDerived().TransformOMPExecutableDirective(D);
getDerived().getSema().EndOpenMPDSABlock(Res.get());
return Res;
}
//===----------------------------------------------------------------------===//
// OpenMP clause transformation

View File

@ -5990,6 +5990,8 @@ void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
TL.setLocalRangeBegin(ReadSourceLocation());
TL.setLParenLoc(ReadSourceLocation());
TL.setRParenLoc(ReadSourceLocation());
TL.setExceptionSpecRange(SourceRange(Reader->ReadSourceLocation(*F, Record, Idx),
Reader->ReadSourceLocation(*F, Record, Idx)));
TL.setLocalRangeEnd(ReadSourceLocation());
for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) {
TL.setParam(i, Reader->ReadDeclAs<ParmVarDecl>(*F, Record, Idx));

View File

@ -748,6 +748,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->IsExplicitlyDefaulted = Record.readInt();
FD->HasImplicitReturnZero = Record.readInt();
FD->IsConstexpr = Record.readInt();
FD->UsesSEHTry = Record.readInt();
FD->HasSkippedBody = Record.readInt();
FD->IsLateTemplateParsed = Record.readInt();
FD->setCachedLinkage(Linkage(Record.readInt()));

View File

@ -2865,6 +2865,11 @@ void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
VisitOMPLoopDirective(D);
}
void ASTStmtReader::VisitOMPTargetTeamsDistributeSimdDirective(
OMPTargetTeamsDistributeSimdDirective *D) {
VisitOMPLoopDirective(D);
}
//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
@ -3651,6 +3656,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
}
case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE: {
auto NumClauses = Record[ASTStmtReader::NumStmtFields];
auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
S = OMPTargetTeamsDistributeSimdDirective::CreateEmpty(
Context, NumClauses, CollapsedNum, Empty);
break;
}
case EXPR_CXX_OPERATOR_CALL:
S = new (Context) CXXOperatorCallExpr(Context, Empty);
break;

View File

@ -629,6 +629,7 @@ void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
Record.AddSourceLocation(TL.getLocalRangeBegin());
Record.AddSourceLocation(TL.getLParenLoc());
Record.AddSourceLocation(TL.getRParenLoc());
Record.AddSourceRange(TL.getExceptionSpecRange());
Record.AddSourceLocation(TL.getLocalRangeEnd());
for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
Record.AddDeclRef(TL.getParam(i));

View File

@ -529,6 +529,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->IsExplicitlyDefaulted);
Record.push_back(D->HasImplicitReturnZero);
Record.push_back(D->IsConstexpr);
Record.push_back(D->UsesSEHTry);
Record.push_back(D->HasSkippedBody);
Record.push_back(D->IsLateTemplateParsed);
Record.push_back(D->getLinkageInternal());
@ -2032,6 +2033,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage

View File

@ -2563,6 +2563,12 @@ void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
}
void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
OMPTargetTeamsDistributeSimdDirective *D) {
VisitOMPLoopDirective(D);
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
}
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//

View File

@ -515,8 +515,9 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
Init = ASE->getBase()->IgnoreImplicit();
SVal LValue = State->getSVal(Init, stackFrame);
if (Optional<Loc> LValueLoc = LValue.getAs<Loc>())
InitVal = State->getSVal(*LValueLoc);
if (!Field->getType()->isReferenceType())
if (Optional<Loc> LValueLoc = LValue.getAs<Loc>())
InitVal = State->getSVal(*LValueLoc);
// If we fail to get the value for some reason, use a symbolic value.
if (InitVal.isUnknownOrUndef()) {
@ -870,6 +871,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::OMPTargetTeamsDistributeDirectiveClass:
case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
llvm_unreachable("Stmt should not be in analyzer evaluation loop");
case Stmt::ObjCSubscriptRefExprClass:

View File

@ -218,6 +218,18 @@ SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
}
DefinedSVal SValBuilder::getMemberPointer(const DeclaratorDecl* DD) {
assert(!DD || isa<CXXMethodDecl>(DD) || isa<FieldDecl>(DD));
if (auto *MD = dyn_cast_or_null<CXXMethodDecl>(DD)) {
// Sema treats pointers to static member functions as have function pointer
// type, so return a function pointer for the method.
// We don't need to play a similar trick for static member fields
// because these are represented as plain VarDecls and not FieldDecls
// in the AST.
if (MD->isStatic())
return getFunctionPointer(MD);
}
return nonloc::PointerToMember(DD);
}

View File

@ -197,3 +197,10 @@ namespace ReferenceInitialization {
}
};
namespace PR31592 {
struct C {
C() : f("}") { } // no-crash
const char(&f)[2];
};
}

View File

@ -77,7 +77,8 @@ bool testDereferencing() {
namespace testPointerToMemberFunction {
struct A {
virtual int foo() { return 1; }
int bar() { return 2; }
int bar() { return 2; }
int static staticMemberFunction(int p) { return p + 1; };
};
struct B : public A {
@ -111,11 +112,19 @@ namespace testPointerToMemberFunction {
clang_analyzer_eval((APtr->*AFP)() == 3); // expected-warning{{TRUE}}
}
void testPointerToStaticMemberCall() {
int (*fPtr)(int) = &A::staticMemberFunction;
if (fPtr != 0) { // no-crash
clang_analyzer_eval(fPtr(2) == 3); // expected-warning{{TRUE}}
}
}
} // end of testPointerToMemberFunction namespace
namespace testPointerToMemberData {
struct A {
int i;
static int j;
};
void testPointerToMemberData() {
@ -126,6 +135,13 @@ namespace testPointerToMemberData {
a.*AMdPointer += 1;
clang_analyzer_eval(a.i == 43); // expected-warning{{TRUE}}
int *ptrToStaticField = &A::j;
if (ptrToStaticField != 0) {
*ptrToStaticField = 7;
clang_analyzer_eval(*ptrToStaticField == 7); // expected-warning{{TRUE}}
clang_analyzer_eval(A::j == 7); // expected-warning{{TRUE}}
}
}
} // end of testPointerToMemberData namespace

View File

@ -315,6 +315,32 @@ void testConsistencyAssign(Person *p) {
}
@end
__attribute__((objc_root_class))
@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
@end
@protocol HasStuff
@property (nonatomic, readonly) int stuffProperty;
@end
@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private)
@property (nonatomic, readonly) int stuffProperty;
@end
@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff>
@end
@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff>
@end
@implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
@synthesize stuffProperty = _stuffProperty;
-(void)foo {
(void)self.stuffProperty;
}
@end
//------
// Setter ivar invalidation.
//------

View File

@ -0,0 +1,21 @@
// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++11
// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++14
// expected-no-diagnostics
struct foo_t {
union {
int i;
volatile int j;
} u;
};
__attribute__((__require_constant_initialization__))
static const foo_t x = {{0}};
union foo_u {
int i;
volatile int j;
};
__attribute__((__require_constant_initialization__))
static const foo_u y = {0};

View File

@ -1032,7 +1032,7 @@ namespace dr91 { // dr91: yes
int k = f(U());
}
namespace dr92 { // dr92: 4.0 c++17
namespace dr92 { // dr92: 4 c++17
void f() throw(int, float); // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
void (*p)() throw(int) = &f; // expected-error 0-1{{ISO C++1z does not allow}} expected-note 0-1{{use 'noexcept}}
#if __cplusplus <= 201402L

View File

@ -3,7 +3,7 @@
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
namespace dr1213 { // dr1213: 4.0
namespace dr1213 { // dr1213: 4
#if __cplusplus >= 201103L
using T = int[3];
int &&r = T{}[1];
@ -26,7 +26,7 @@ struct Derived : Base {
};
} // dr1250
namespace dr1295 { // dr1295: 4.0
namespace dr1295 { // dr1295: 4
struct X {
unsigned bitfield : 4;
};

View File

@ -31,7 +31,7 @@ namespace dr1315 { // dr1315: partial
// expected-error@-1 {{type of specialized non-type template argument depends on a template parameter of the partial specialization}}
}
namespace dr1330 { // dr1330: 4.0 c++11
namespace dr1330 { // dr1330: 4 c++11
// exception-specifications are parsed in a context where the class is complete.
struct A {
void f() throw(T) {} // expected-error 0-1{{C++1z}} expected-note 0-1{{noexcept}}
@ -175,7 +175,7 @@ namespace dr1359 { // dr1359: 3.5
#endif
}
namespace dr1388 { // dr1388: 4.0
namespace dr1388 { // dr1388: 4
template<typename A, typename ...T> void f(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}
template<typename ...T> void g(T..., int); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}
template<typename ...T, typename A> void h(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}

View File

@ -343,7 +343,7 @@ namespace dr1490 { // dr1490: 3.7 c++11
std::initializer_list<char>{"abc"}; // expected-error {{expected unqualified-id}}}
} // dr190
namespace dr1495 { // dr1495: 4.0
namespace dr1495 { // dr1495: 4
// Deduction succeeds in both directions.
template<typename T, typename U> struct A {}; // expected-note {{template is declared here}}
template<typename T, typename U> struct A<U, T> {}; // expected-error {{class template partial specialization is not more specialized}}

View File

@ -3,7 +3,7 @@
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
namespace dr1512 { // dr1512: 4.0
namespace dr1512 { // dr1512: 4
void f(char *p) {
if (p > 0) {} // expected-error {{ordered comparison between pointer and zero}}
#if __cplusplus >= 201103L
@ -135,7 +135,7 @@ namespace dr1512 { // dr1512: 4.0
}
}
namespace dr1518 { // dr1518: 4.0
namespace dr1518 { // dr1518: 4
#if __cplusplus >= 201103L
struct Z0 { // expected-note 0+ {{candidate}}
explicit Z0() = default; // expected-note 0+ {{here}}

View File

@ -86,7 +86,7 @@ namespace dr1645 { // dr1645: 3.9
#endif
}
namespace dr1653 { // dr1653: 4.0 c++17
namespace dr1653 { // dr1653: 4 c++17
void f(bool b) {
++b;
b++;

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