Updating branches/google/stable to r239765

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/stable@240080 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2015-06-18 23:36:39 +00:00
Родитель ec0f4f5aa6 5d1cad0624
Коммит eb564dc816
1108 изменённых файлов: 42883 добавлений и 19235 удалений

Просмотреть файл

@ -182,6 +182,9 @@ set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." )
set(DEFAULT_SYSROOT "" CACHE PATH
"Default <path> to all compiler invocations for --sysroot=<path>." )
set(CLANG_DEFAULT_OPENMP_RUNTIME "libgomp" CACHE STRING
"Default OpenMP runtime used by -fopenmp.")
set(CLANG_VENDOR "" CACHE STRING
"Vendor-specific text for showing with version information.")
@ -317,6 +320,17 @@ function(clang_tablegen)
endif()
endfunction(clang_tablegen)
macro(set_clang_windows_version_resource_properties name)
if(DEFINED windows_resource_file)
set_windows_version_resource_properties(${name} ${windows_resource_file}
VERSION_MAJOR ${CLANG_VERSION_MAJOR}
VERSION_MINOR ${CLANG_VERSION_MINOR}
VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL}
VERSION_STRING "${CLANG_VERSION} (${BACKEND_PACKAGE_STRING})"
PRODUCT_NAME "clang")
endif()
endmacro()
macro(add_clang_library name)
cmake_parse_arguments(ARG
""
@ -362,6 +376,7 @@ macro(add_clang_library name)
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
install(TARGETS ${name}
EXPORT ClangTargets
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
RUNTIME DESTINATION bin)
@ -373,11 +388,13 @@ macro(add_clang_library name)
endif()
set_target_properties(${name} PROPERTIES FOLDER "Clang libraries")
set_clang_windows_version_resource_properties(${name})
endmacro(add_clang_library)
macro(add_clang_executable name)
add_llvm_executable( ${name} ${ARGN} )
set_target_properties(${name} PROPERTIES FOLDER "Clang executables")
set_clang_windows_version_resource_properties(${name})
endmacro(add_clang_executable)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
@ -521,9 +538,10 @@ if (CLANG_BUILT_STANDALONE)
# Install a <prefix>/share/clang/cmake/ClangConfig.cmake file so that
# find_package(Clang) works. Install the target list with it.
install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake
${CLANG_BINARY_DIR}/share/clang/cmake/ClangTargets.cmake
DESTINATION share/clang/cmake)
# Also copy ClangConfig.cmake to the build directory so that dependent projects

Просмотреть файл

@ -12,6 +12,10 @@ N: Aaron Ballman
E: aaron@aaronballman.com
D: Clang attributes
N: Alexey Bataev
E: a.bataev@hotmail.com
D: OpenMP support
N: Chandler Carruth
E: chandlerc@gmail.com
E: chandlerc@google.com

Просмотреть файл

@ -160,6 +160,17 @@ the configuration (without a prefix: ``Auto``).
argument2);
\endcode
**AlignConsecutiveAssignments** (``bool``)
If ``true``, aligns consecutive assignments.
This will align the assignment operators of consecutive lines. This
will result in formattings like
\code
int aaaa = 12;
int b = 23;
int ccc = 23;
\endcode
**AlignEscapedNewlinesLeft** (``bool``)
If ``true``, aligns escaped newlines as far left as possible.
Otherwise puts them into the right-most column.
@ -191,10 +202,10 @@ the configuration (without a prefix: ``Auto``).
* ``SFS_None`` (in configuration: ``None``)
Never merge functions into a single line.
* ``SFS_Inline`` (in configuration: ``Inline``)
Only merge functions defined inside a class.
* ``SFS_Empty`` (in configuration: ``Empty``)
Only merge empty functions.
* ``SFS_Inline`` (in configuration: ``Inline``)
Only merge functions defined inside a class. Implies "empty".
* ``SFS_All`` (in configuration: ``All``)
Merge all functions fitting on a single line.

Просмотреть файл

@ -110,7 +110,7 @@ will be chosen, so you'll almost always have to change it via flags.
Typical flags include:
* ``-mcpu=<cpu-name>``, like x86-64, swift, cortex-a15
* ``-fpu=<fpu-name>``, like SSE3, NEON, controlling the FP unit available
* ``-mfpu=<fpu-name>``, like SSE3, NEON, controlling the FP unit available
* ``-mfloat-abi=<fabi>``, like soft, hard, controlling which registers
to use for floating-point

Просмотреть файл

@ -138,12 +138,12 @@ The driver functionality is conceptually divided into five stages:
this vector instead of storing its values directly.
The clang driver can dump the results of this stage using the
``-ccc-print-options`` flag (which must precede any actual command
``-###`` flag (which must precede any actual command
line arguments). For example:
.. code-block:: console
$ clang -ccc-print-options -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c
$ clang -### -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c
Option 0 - Name: "-Xarch_", Values: {"i386", "-fomit-frame-pointer"}
Option 1 - Name: "-Wa,", Values: {"-fast"}
Option 2 - Name: "-I", Values: {"foo"}

Просмотреть файл

@ -1621,192 +1621,304 @@ How to change Clang
How to add an attribute
-----------------------
Attributes are a form of metadata that can be attached to a program construct,
allowing the programmer to pass semantic information along to the compiler for
various uses. For example, attributes may be used to alter the code generation
for a program construct, or to provide extra semantic information for static
analysis. This document explains how to add a custom attribute to Clang.
Documentation on existing attributes can be found `here
<//clang.llvm.org/docs/AttributeReference.html>`_.
Attribute Basics
^^^^^^^^^^^^^^^^
Attributes in Clang are handled in three stages: parsing into a parsed attribute
representation, conversion from a parsed attribute into a semantic attribute,
and then the semantic handling of the attribute.
Attributes in clang come in two forms: parsed form, and semantic form. Both
forms are represented via a tablegen definition of the attribute, specified in
Attr.td.
Parsing of the attribute is determined by the various syntactic forms attributes
can take, such as GNU, C++11, and Microsoft style attributes, as well as other
information provided by the table definition of the attribute. Ultimately, the
parsed representation of an attribute object is an ``AttributeList`` object.
These parsed attributes chain together as a list of parsed attributes attached
to a declarator or declaration specifier. The parsing of attributes is handled
automatically by Clang, except for attributes spelled as keywords. When
implementing a keyword attribute, the parsing of the keyword and creation of the
``AttributeList`` object must be done manually.
Eventually, ``Sema::ProcessDeclAttributeList()`` is called with a ``Decl`` and
an ``AttributeList``, at which point the parsed attribute can be transformed
into a semantic attribute. The process by which a parsed attribute is converted
into a semantic attribute depends on the attribute definition and semantic
requirements of the attribute. The end result, however, is that the semantic
attribute object is attached to the ``Decl`` object, and can be obtained by a
call to ``Decl::getAttr<T>()``.
The structure of the semantic attribute is also governed by the attribute
definition given in Attr.td. This definition is used to automatically generate
functionality used for the implementation of the attribute, such as a class
derived from ``clang::Attr``, information for the parser to use, automated
semantic checking for some attributes, etc.
``include/clang/Basic/Attr.td``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The first step to adding a new attribute to Clang is to add its definition to
`include/clang/Basic/Attr.td
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup>`_.
This tablegen definition must derive from the ``Attr`` (tablegen, not
semantic) type, or one of its derivatives. Most attributes will derive from the
``InheritableAttr`` type, which specifies that the attribute can be inherited by
later redeclarations of the ``Decl`` it is associated with.
``InheritableParamAttr`` is similar to ``InheritableAttr``, except that the
attribute is written on a parameter instead of a declaration. If the attribute
is intended to apply to a type instead of a declaration, such an attribute
should derive from ``TypeAttr``, and will generally not be given an AST
representation. (Note that this document does not cover the creation of type
attributes.) An attribute that inherits from ``IgnoredAttr`` is parsed, but will
generate an ignored attribute diagnostic when used, which may be useful when an
attribute is supported by another vendor but not supported by clang.
First, add your attribute to the `include/clang/Basic/Attr.td
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup>`_
file.
The definition will specify several key pieces of information, such as the
semantic name of the attribute, the spellings the attribute supports, the
arguments the attribute expects, and more. Most members of the ``Attr`` tablegen
type do not require definitions in the derived definition as the default
suffice. However, every attribute must specify at least a spelling list, a
subject list, and a documentation list.
Each attribute gets a ``def`` inheriting from ``Attr`` or one of its
subclasses. ``InheritableAttr`` means that the attribute also applies to
subsequent declarations of the same name. ``InheritableParamAttr`` is similar
to ``InheritableAttr``, except that the attribute is written on a parameter
instead of a declaration, type or statement. Attributes inheriting from
``TypeAttr`` are pure type attributes which generally are not given a
representation in the AST. Attributes inheriting from ``TargetSpecificAttr``
are attributes specific to one or more target architectures. An attribute that
inherits from ``IgnoredAttr`` is parsed, but will generate an ignored attribute
diagnostic when used. The attribute type may be useful when an attribute is
supported by another vendor, but not supported by clang.
Spellings
~~~~~~~~~
All attributes are required to specify a spelling list that denotes the ways in
which the attribute can be spelled. For instance, a single semantic attribute
may have a keyword spelling, as well as a C++11 spelling and a GNU spelling. An
empty spelling list is also permissible and may be useful for attributes which
are created implicitly. The following spellings are accepted:
``Spellings`` lists the strings that can appear in ``__attribute__((here))`` or
``[[here]]``. All such strings will be synonymous. Possible ``Spellings``
are: ``GNU`` (for use with GNU-style __attribute__ spellings), ``Declspec``
(for use with Microsoft Visual Studio-style __declspec spellings), ``CXX11`
(for use with C++11-style [[foo]] and [[foo::bar]] spellings), and ``Keyword``
(for use with attributes that are implemented as keywords, like C++11's
``override`` or ``final``). If you want to allow the ``[[]]`` C++11 syntax, you
have to define a list of ``Namespaces``, which will let users write
``[[namespace::spelling]]``. Using the empty string for a namespace will allow
users to write just the spelling with no "``::``". Attributes which g++-4.8
or later accepts should also have a ``CXX11<"gnu", "spelling">`` spelling.
============ ================================================================
Spelling Description
============ ================================================================
``GNU`` Spelled with a GNU-style ``__attribute__((attr))`` syntax and
placement.
``CXX11`` Spelled with a C++-style ``[[attr]]`` syntax. If the attribute
is meant to be used by Clang, it should set the namespace to
``"clang"``.
``Declspec`` Spelled with a Microsoft-style ``__declspec(attr)`` syntax.
``Keyword`` The attribute is spelled as a keyword, and required custom
parsing.
``GCC`` Specifies two spellings: the first is a GNU-style spelling, and
the second is a C++-style spelling with the ``gnu`` namespace.
Attributes should only specify this spelling for attributes
supported by GCC.
``Pragma`` The attribute is spelled as a ``#pragma``, and requires custom
processing within the preprocessor. If the attribute is meant to
be used by Clang, it should set the namespace to ``"clang"``.
Note that this spelling is not used for declaration attributes.
============ ================================================================
``Subjects`` restricts what kinds of AST node to which this attribute can
appertain (roughly, attach). The subjects are specified via a ``SubjectList``,
which specify the list of subjects. Additionally, subject-related diagnostics
can be specified to be warnings or errors, with the default being a warning.
The diagnostics displayed to the user are automatically determined based on
the subjects in the list, but a custom diagnostic parameter can also be
specified in the ``SubjectList``. The diagnostics generated for subject list
violations are either ``diag::warn_attribute_wrong_decl_type`` or
``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is
found in `include/clang/Sema/AttributeList.h
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup>`_
If you add new Decl nodes to the ``SubjectList``, you may need to update the
logic used to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp
<http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_.
Subjects
~~~~~~~~
Attributes appertain to one or more ``Decl`` subjects. If the attribute attempts
to attach to a subject that is not in the subject list, a diagnostic is issued
automatically. Whether the diagnostic is a warning or an error depends on how
the attribute's ``SubjectList`` is defined, but the default behavior is to warn.
The diagnostics displayed to the user are automatically determined based on the
subjects in the list, but a custom diagnostic parameter can also be specified in
the ``SubjectList``. The diagnostics generated for subject list violations are
either ``diag::warn_attribute_wrong_decl_type`` or
``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found
in `include/clang/Sema/AttributeList.h
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup>`_
If a previously unused Decl node is added to the ``SubjectList``, the logic used
to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp
<http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
may need to be updated.
Diagnostic checking for attribute subject lists is automated except when
``HasCustomParsing`` is set to ``1``.
By default, all subjects in the SubjectList must either be a Decl node defined
in ``DeclNodes.td``, or a statement node defined in ``StmtNodes.td``. However,
more complex subjects can be created by creating a ``SubsetSubject`` object.
Each such object has a base subject which it appertains to (which must be a
Decl or Stmt node, and not a SubsetSubject node), and some custom code which is
called when determining whether an attribute appertains to the subject. For
instance, a ``NonBitField`` SubsetSubject appertains to a ``FieldDecl``, and
tests whether the given FieldDecl is a bit field. When a SubsetSubject is
By default, all subjects in the SubjectList must either be a Decl node defined
in ``DeclNodes.td``, or a statement node defined in ``StmtNodes.td``. However,
more complex subjects can be created by creating a ``SubsetSubject`` object.
Each such object has a base subject which it appertains to (which must be a
Decl or Stmt node, and not a SubsetSubject node), and some custom code which is
called when determining whether an attribute appertains to the subject. For
instance, a ``NonBitField`` SubsetSubject appertains to a ``FieldDecl``, and
tests whether the given FieldDecl is a bit field. When a SubsetSubject is
specified in a SubjectList, a custom diagnostic parameter must also be provided.
``Args`` names the arguments the attribute takes, in order. If ``Args`` is
Diagnostic checking for attribute subject lists is automated except when
``HasCustomParsing`` is set to ``1``.
Documentation
~~~~~~~~~~~~~
All attributes must have some form of documentation associated with them.
Documentation is table generated on the public web server by a server-side
process that runs daily. Generally, the documentation for an attribute is a
stand-alone definition in `include/clang/Basic/AttrDocs.td
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttdDocs.td?view=markup>`_
that is named after the attribute being documented.
If the attribute is not for public consumption, or is an implicitly-created
attribute that has no visible spelling, the documentation list can specify the
``Undocumented`` object. Otherwise, the attribute should have its documentation
added to AttrDocs.td.
Documentation derives from the ``Documentation`` tablegen type. All derived
types must specify a documentation category and the actual documentation itself.
Additionally, it can specify a custom heading for the attribute, though a
default heading will be chosen when possible.
There are four predefined documentation categories: ``DocCatFunction`` for
attributes that appertain to function-like subjects, ``DocCatVariable`` for
attributes that appertain to variable-like subjects, ``DocCatType`` for type
attributes, and ``DocCatStmt`` for statement attributes. A custom documentation
category should be used for groups of attributes with similar functionality.
Custom categories are good for providing overview information for the attributes
grouped under it. For instance, the consumed annotation attributes define a
custom category, ``DocCatConsumed``, that explains what consumed annotations are
at a high level.
Documentation content (whether it is for an attribute or a category) is written
using reStructuredText (RST) syntax.
After writing the documentation for the attribute, it should be locally tested
to ensure that there are no issues generating the documentation on the server.
Local testing requires a fresh build of clang-tblgen. To generate the attribute
documentation, execute the following command::
clang-tblgen -gen-attr-docs -I /path/to/clang/include /path/to/clang/include/clang/Basic/Attr.td -o /path/to/clang/docs/AttributeReference.rst
When testing locally, *do not* commit changes to ``AttributeReference.rst``.
This file is generated by the server automatically, and any changes made to this
file will be overwritten.
Arguments
~~~~~~~~~
Attributes may optionally specify a list of arguments that can be passed to the
attribute. Attribute arguments specify both the parsed form and the semantic
form of the attribute. For example, if ``Args`` is
``[StringArgument<"Arg1">, IntArgument<"Arg2">]`` then
``__attribute__((myattribute("Hello", 3)))`` will be a valid use. Attribute
arguments specify both the parsed form and the semantic form of the attribute.
The previous example shows an attribute which requires two attributes while
parsing, and the Attr subclass' constructor for the attribute will require a
string and integer argument.
``__attribute__((myattribute("Hello", 3)))`` will be a valid use; it requires
two arguments while parsing, and the Attr subclass' constructor for the
semantic attribute will require a string and integer argument.
Diagnostic checking for argument counts is automated except when
``HasCustomParsing`` is set to ``1``, or when the attribute uses an optional or
variadic argument. Diagnostic checking for argument semantics is not automated.
All arguments have a name and a flag that specifies whether the argument is
optional. The associated C++ type of the argument is determined by the argument
definition type. If the existing argument types are insufficient, new types can
be created, but it requires modifying `utils/TableGen/ClangAttrEmitter.cpp
<http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
to properly support the type.
If the parsed form of the attribute is more complex, or differs from the
semantic form, the ``HasCustomParsing`` bit can be set to ``1`` for the class,
and the parsing code in `Parser::ParseGNUAttributeArgs
<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup>`_
can be updated for the special case. Note that this only applies to arguments
with a GNU spelling -- attributes with a __declspec spelling currently ignore
Other Properties
~~~~~~~~~~~~~~~~
The ``Attr`` definition has other members which control the behavior of the
attribute. Many of them are special-purpose and beyond the scope of this
document, however a few deserve mention.
If the parsed form of the attribute is more complex, or differs from the
semantic form, the ``HasCustomParsing`` bit can be set to ``1`` for the class,
and the parsing code in `Parser::ParseGNUAttributeArgs()
<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup>`_
can be updated for the special case. Note that this only applies to arguments
with a GNU spelling -- attributes with a __declspec spelling currently ignore
this flag and are handled by ``Parser::ParseMicrosoftDeclSpec``.
Custom accessors can be generated for an attribute based on the spelling list
for that attribute. For instance, if an attribute has two different spellings:
'Foo' and 'Bar', accessors can be created:
``[Accessor<"isFoo", [GNU<"Foo">]>, Accessor<"isBar", [GNU<"Bar">]>]``
These accessors will be generated on the semantic form of the attribute,
accepting no arguments and returning a Boolean.
Note that setting this member to 1 will opt out of common attribute semantic
handling, requiring extra implementation efforts to ensure the attribute
appertains to the appropriate subject, etc.
Attributes which do not require an AST node should set the ``ASTNode`` field to
``0`` to avoid polluting the AST. Note that anything inheriting from
``TypeAttr`` or ``IgnoredAttr`` automatically do not generate an AST node. All
other attributes generate an AST node by default. The AST node is the semantic
If the attribute should not be propagated from from a template declaration to an
instantiation of the template, set the ``Clone`` member to 0. By default, all
attributes will be cloned to template instantiations.
Attributes that do not require an AST node should set the ``ASTNode`` field to
``0`` to avoid polluting the AST. Note that anything inheriting from
``TypeAttr`` or ``IgnoredAttr`` automatically do not generate an AST node. All
other attributes generate an AST node by default. The AST node is the semantic
representation of the attribute.
Attributes which do not require custom semantic handling should set the
``SemaHandler`` field to ``0``. Note that anything inheriting from
``IgnoredAttr`` automatically do not get a semantic handler. All other
attributes are assumed to use a semantic handler by default. Attributes
without a semantic handler are not given a parsed attribute Kind enumeration.
The ``LangOpts`` field specifies a list of language options required by the
attribute. For instance, all of the CUDA-specific attributes specify ``[CUDA]``
for the ``LangOpts`` field, and when the CUDA language option is not enabled, an
"attribute ignored" warning diagnostic is emitted. Since language options are
not table generated nodes, new language options must be created manually and
should specify the spelling used by ``LangOptions`` class.
The ``LangOpts`` field can be used to specify a list of language options
required by the attribute. For instance, all of the CUDA-specific attributes
specify ``[CUDA]`` for the ``LangOpts`` field, and when the CUDA language
option is not enabled, an "attribute ignored" warning diagnostic is emitted.
Since language options are not table generated nodes, new language options must
be created manually and should specify the spelling used by ``LangOptions`` class.
Custom accessors can be generated for an attribute based on the spelling list
for that attribute. For instance, if an attribute has two different spellings:
'Foo' and 'Bar', accessors can be created:
``[Accessor<"isFoo", [GNU<"Foo">]>, Accessor<"isBar", [GNU<"Bar">]>]``
These accessors will be generated on the semantic form of the attribute,
accepting no arguments and returning a ``bool``.
Target-specific attribute sometimes share a spelling with other attributes in
different targets. For instance, the ARM and MSP430 targets both have an
attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic
requirements. To support this feature, an attribute inheriting from
``TargetSpecificAttribute`` make specify a ``ParseKind`` field. This field
should be the same value between all arguments sharing a spelling, and
corresponds to the parsed attribute's Kind enumeration. This allows attributes
to share a parsed attribute kind, but have distinct semantic attribute classes.
For instance, ``AttributeList::AT_Interrupt`` is the shared parsed attribute
kind, but ARMInterruptAttr and MSP430InterruptAttr are the semantic attributes
generated.
Attributes that do not require custom semantic handling should set the
``SemaHandler`` field to ``0``. Note that anything inheriting from
``IgnoredAttr`` automatically do not get a semantic handler. All other
attributes are assumed to use a semantic handler by default. Attributes
without a semantic handler are not given a parsed attribute ``Kind`` enumerator.
By default, when declarations are merging attributes, an attribute will not be
duplicated. However, if an attribute can be duplicated during this merging
stage, set ``DuplicatesAllowedWhileMerging`` to ``1``, and the attribute will
Target-specific attributes may share a spelling with other attributes in
different targets. For instance, the ARM and MSP430 targets both have an
attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic
requirements. To support this feature, an attribute inheriting from
``TargetSpecificAttribute`` may specify a ``ParseKind`` field. This field
should be the same value between all arguments sharing a spelling, and
corresponds to the parsed attribute's ``Kind`` enumerator. This allows
attributes to share a parsed attribute kind, but have distinct semantic
attribute classes. For instance, ``AttributeList::AT_Interrupt`` is the shared
parsed attribute kind, but ARMInterruptAttr and MSP430InterruptAttr are the
semantic attributes generated.
By default, when declarations are merging attributes, an attribute will not be
duplicated. However, if an attribute can be duplicated during this merging
stage, set ``DuplicatesAllowedWhileMerging`` to ``1``, and the attribute will
be merged.
By default, attribute arguments are parsed in an evaluated context. If the
arguments for an attribute should be parsed in an unevaluated context (akin to
the way the argument to a ``sizeof`` expression is parsed), you can set
By default, attribute arguments are parsed in an evaluated context. If the
arguments for an attribute should be parsed in an unevaluated context (akin to
the way the argument to a ``sizeof`` expression is parsed), set
``ParseArgumentsAsUnevaluated`` to ``1``.
If additional functionality is desired for the semantic form of the attribute,
the ``AdditionalMembers`` field specifies code to be copied verbatim into the
semantic attribute class object.
All attributes must have one or more form of documentation, which is provided
in the ``Documentation`` list. Generally, the documentation for an attribute
is a stand-alone definition in `include/clang/Basic/AttrDocs.td
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttdDocs.td?view=markup>`_
that is named after the attribute being documented. Each documentation element
is given a ``Category`` (variable, function, or type) and ``Content``. A single
attribute may contain multiple documentation elements for distinct categories.
For instance, an attribute which can appertain to both function and types (such
as a calling convention attribute), should contain two documentation elements.
The ``Content`` for an attribute uses reStructuredText (RST) syntax.
If an attribute is used internally by the compiler, but is not written by users
(such as attributes with an empty spelling list), it can use the
``Undocumented`` documentation element.
If additional functionality is desired for the semantic form of the attribute,
the ``AdditionalMembers`` field specifies code to be copied verbatim into the
semantic attribute class object, with ``public`` access.
Boilerplate
^^^^^^^^^^^
All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp
<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup>`_,
and generally starts in the ``ProcessDeclAttribute`` function. If your
attribute is a "simple" attribute -- meaning that it requires no custom
semantic processing aside from what is automatically provided for you, you can
add a call to ``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the switch
statement. Otherwise, write a new ``handleYourAttr()`` function, and add that
to the switch statement.
<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup>`_,
and generally starts in the ``ProcessDeclAttribute()`` function. If the
attribute is a "simple" attribute -- meaning that it requires no custom semantic
processing aside from what is automatically provided, add a call to
``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the switch statement.
Otherwise, write a new ``handleYourAttr()`` function, and add that to the switch
statement. Please do not implement handling logic directly in the ``case`` for
the attribute.
If your attribute causes extra warnings to fire, define a ``DiagGroup`` in
Unless otherwise specified by the attribute definition, common semantic checking
of the parsed attribute is handled automatically. This includes diagnosing
parsed attributes that do not appertain to the given ``Decl``, ensuring the
correct minimum number of arguments are passed, etc.
If the attribute adds additional warnings, define a ``DiagGroup`` in
`include/clang/Basic/DiagnosticGroups.td
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?view=markup>`_
named after the attribute's ``Spelling`` with "_"s replaced by "-"s. If you're
only defining one diagnostic, you can skip ``DiagnosticGroups.td`` and use
``InGroup<DiagGroup<"your-attribute">>`` directly in `DiagnosticSemaKinds.td
named after the attribute's ``Spelling`` with "_"s replaced by "-"s. If there
is only a single diagnostic, it is permissible to use ``InGroup<DiagGroup<"your-attribute">>``
directly in `DiagnosticSemaKinds.td
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup>`_
All semantic diagnostics generated for your attribute, including automatically-
generated ones (such as subjects and argument counts), should have a
generated ones (such as subjects and argument counts), should have a
corresponding test case.
The meat of your attribute
^^^^^^^^^^^^^^^^^^^^^^^^^^
Semantic handling
^^^^^^^^^^^^^^^^^
Most attributes are implemented to have some effect on the compiler. For
instance, to modify the way code is generated, or to add extra semantic checks
for an analysis pass, etc. Having added the attribute definition and conversion
to the semantic representation for the attribute, what remains is to implement
the custom logic requiring use of the attribute.
Find an appropriate place in Clang to do whatever your attribute needs to do.
Check for the attribute's presence using ``Decl::getAttr<YourAttr>()``.
Update the :doc:`LanguageExtensions` document to describe your new attribute.
The ``clang::Decl`` object can be queried for the presence or absence of an
attribute using ``hasAttr<T>()``. To obtain a pointer to the semantic
representation of the attribute, ``getAttr<T>`` may be used.
How to add an expression or statement
-------------------------------------

Просмотреть файл

@ -1845,6 +1845,9 @@ with :doc:`ThreadSanitizer`.
Use ``__has_feature(memory_sanitizer)`` to check if the code is being built
with :doc:`MemorySanitizer`.
Use ``__has_feature(safe_stack)`` to check if the code is being built
with :doc:`SafeStack`.
Extensions for selectively disabling optimization
=================================================

Просмотреть файл

@ -169,7 +169,7 @@ You should now be able to run the syntax checker, which is located in
.. code-block:: console
cat "int main() { return 0; }" > test.cpp
echo "int main() { return 0; }" > test.cpp
bin/loop-convert test.cpp --
Note the two dashes after we specify the source file. The additional

Просмотреть файл

@ -84,14 +84,23 @@ The status of major ABI-impacting C++ features:
* RTTI: :good:`Complete`. Generation of RTTI data structures has been
finished, along with support for the ``/GR`` flag.
* Exceptions and SEH: :partial:`Minimal`. Clang can parse both constructs, but
does not know how to emit compatible handlers. Clang can throw and rethrow
C++ exceptions.
* Exceptions and SEH: :partial:`Partial`.
C++ exceptions (``try`` / ``catch`` / ``throw``) and
structured exceptions (``__try`` / ``__except`` / ``__finally``) mostly
work on x64. 32-bit exception handling support is being worked on. LLVM does
not model asynchronous exceptions, so it is currently impossible to catch an
asynchronous exception generated in the same frame as the catching ``__try``.
C++ exception specifications are ignored, but this is `consistent with Visual
C++`_.
* Thread-safe initialization of local statics: :none:`Unstarted`. We are ABI
compatible with MSVC 2013, which does not support thread-safe local statics.
MSVC "14" changed the ABI to make initialization of local statics thread safe,
and we have not yet implemented this.
.. _consistent with Visual C++:
https://msdn.microsoft.com/en-us/library/wfa0edys.aspx
* Thread-safe initialization of local statics: :good:`Complete`. MSVC 2015
added support for thread-safe initialization of such variables by taking an
ABI break.
We are ABI compatible with both the MSVC 2013 and 2015 ABI for static local
variables.
* Lambdas: :good:`Mostly complete`. Clang is compatible with Microsoft's
implementation of lambdas except for providing overloads for conversion to

Просмотреть файл

@ -11,8 +11,8 @@ Written by the `LLVM Team <http://llvm.org/>`_
.. warning::
These are in-progress notes for the upcoming Clang 3.7 release. You may
prefer the `Clang 3.5 Release Notes
<http://llvm.org/releases/3.5.0/tools/clang/docs/ReleaseNotes.html>`_.
prefer the `Clang 3.6 Release Notes
<http://llvm.org/releases/3.6.0/tools/clang/docs/ReleaseNotes.html>`_.
Introduction
============
@ -47,8 +47,10 @@ sections with improvements to Clang's support for those languages.
Major New Features
------------------
- Feature ...
- Use of the ``__declspec`` language extension for declaration attributes now
requires passing the -fms-extensions or -fborland compiler flag. This language
extension is also enabled when compiling CUDA code, but its use should be
viewed as an implementation detail that is subject to change.
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -118,7 +120,13 @@ These are major API changes that have happened since the 3.6 release of
Clang. If upgrading an external codebase that uses Clang as a library,
this section should help get you past the largest hurdles of upgrading.
...
- Some of the `PPCallbacks` interface now deals in `MacroDefinition`
objects instead of `MacroDirective` objects. This allows preserving
full information on macros imported from modules.
- `clang-c/Index.h` no longer `#include`\s `clang-c/Documentation.h`.
You now need to explicitly `#include "clang-c/Documentation.h"` if
you use the libclang documentation API.
libclang
--------

163
docs/SafeStack.rst Normal file
Просмотреть файл

@ -0,0 +1,163 @@
=========
SafeStack
=========
.. contents::
:local:
Introduction
============
SafeStack is an instrumentation pass that protects programs against attacks
based on stack buffer overflows, without introducing any measurable performance
overhead. It works by separating the program stack into two distinct regions:
the safe stack and the unsafe stack. The safe stack stores return addresses,
register spills, and local variables that are always accessed in a safe way,
while the unsafe stack stores everything else. This separation ensures that
buffer overflows on the unsafe stack cannot be used to overwrite anything
on the safe stack, which includes return addresses.
Performance
-----------
The performance overhead of the SafeStack instrumentation is less than 0.1% on
average across a variety of benchmarks (see the `Code-Pointer Integrity
<http://dslab.epfl.ch/pubs/cpi.pdf>`_ paper for details). This is mainly
because most small functions do not have any variables that require the unsafe
stack and, hence, do not need unsafe stack frames to be created. The cost of
creating unsafe stack frames for large functions is amortized by the cost of
executing the function.
In some cases, SafeStack actually improves the performance. Objects that end up
being moved to the unsafe stack are usually large arrays or variables that are
used through multiple stack frames. Moving such objects away from the safe
stack increases the locality of frequently accessed values on the stack, such
as register spills, return addresses, and small local variables.
Limitations
-----------
SafeStack has not been subjected to a comprehensive security review, and there
exist known weaknesses, including but not limited to the following.
In its current state, the separation of local variables provides protection
against stack buffer overflows, but the safe stack itself is not protected
from being corrupted through a pointer dereference. The Code-Pointer
Integrity paper describes two ways in which we may protect the safe stack:
hardware segmentation on the 32-bit x86 architecture or information hiding
on other architectures.
Even with information hiding, the safe stack would merely be hidden
from attackers by being somewhere in the address space. Depending on the
application, the address could be predictable even on 64-bit address spaces
because not all the bits are addressable, multiple threads each have their
stack, the application could leak the safe stack address to memory via
``__builtin_frame_address``, bugs in the low-level runtime support etc.
Safe stack leaks could be mitigated by writing and deploying a static binary
analysis or a dynamic binary instrumentation based tool to find leaks.
This approach doesn't prevent an attacker from "imbalancing" the safe
stack by say having just one call, and doing two rets (thereby returning
to an address that wasn't meant as a return address). This can be at least
partially mitigated by deploying SafeStack alongside a forward control-flow
integrity mechanism to ensure that calls are made using the correct calling
convention. Clang does not currently implement a comprehensive forward
control-flow integrity protection scheme; there exists one that protects
:doc:`virtual calls <ControlFlowIntegrity>` but not non-virtual indirect calls.
Compatibility
-------------
Most programs, static libraries, or individual files can be compiled
with SafeStack as is. SafeStack requires basic runtime support, which, on most
platforms, is implemented as a compiler-rt library that is automatically linked
in when the program is compiled with SafeStack.
Linking a DSO with SafeStack is not currently supported.
Known compatibility limitations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Certain code that relies on low-level stack manipulations requires adaption to
work with SafeStack. One example is mark-and-sweep garbage collection
implementations for C/C++ (e.g., Oilpan in chromium/blink), which must be
changed to look for the live pointers on both safe and unsafe stacks.
SafeStack supports linking together modules that are compiled with and without
SafeStack, both statically and dynamically. One corner case that is not
supported is using ``dlopen()`` to load a dynamic library that uses SafeStack into
a program that is not compiled with SafeStack but uses threads.
Signal handlers that use ``sigaltstack()`` must not use the unsafe stack (see
``__attribute__((no_sanitize("safe-stack")))`` below).
Programs that use APIs from ``ucontext.h`` are not supported yet.
Usage
=====
To enable SafeStack, just pass ``-fsanitize=safe-stack`` flag to both compile and link
command lines.
Supported Platforms
-------------------
SafeStack was tested on Linux, FreeBSD and MacOSX.
Low-level API
-------------
``__has_feature(safe_stack)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some rare cases one may need to execute different code depending on
whether SafeStack is enabled. The macro ``__has_feature(safe_stack)`` can
be used for this purpose.
.. code-block:: c
#if __has_feature(safe_stack)
// code that builds only under SafeStack
#endif
``__attribute__((no_sanitize("safe-stack")))``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use ``__attribute__((no_sanitize("safe-stack")))`` on a function declaration
to specify that the safe stack instrumentation should not be applied to that
function, even if enabled globally (see ``-fsanitize=safe-stack`` flag). This
attribute may be required for functions that make assumptions about the
exact layout of their stack frames.
Care should be taken when using this attribute. The return address is not
protected against stack buffer overflows, and it is easier to leak the
address of the safe stack to memory by taking the address of a local variable.
``__builtin___get_unsafe_stack_ptr()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This builtin function returns current unsafe stack pointer of the current
thread.
``__builtin___get_unsafe_stack_start()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This builtin function returns a pointer to the start of the unsafe stack of the
current thread.
Design
======
Please refer to
`http://dslab.epfl.ch/proj/cpi/ <http://dslab.epfl.ch/proj/cpi/>`_ for more
information about the design of the SafeStack and its related technologies.
Publications
------------
`Code-Pointer Integrity <http://dslab.epfl.ch/pubs/cpi.pdf>`_.
Volodymyr Kuznetsov, Laszlo Szekeres, Mathias Payer, George Candea, R. Sekar, Dawn Song.
USENIX Symposium on Operating Systems Design and Implementation
(`OSDI <https://www.usenix.org/conference/osdi14>`_), Broomfield, CO, October 2014

355
docs/SanitizerCoverage.rst Normal file
Просмотреть файл

@ -0,0 +1,355 @@
=================
SanitizerCoverage
=================
.. contents::
:local:
Introduction
============
Sanitizer tools have a very simple code coverage tool built in. It allows to
get function-level, basic-block-level, and edge-level coverage at a very low
cost.
How to build and run
====================
SanitizerCoverage can be used with :doc:`AddressSanitizer`,
:doc:`LeakSanitizer`, :doc:`MemorySanitizer`, and UndefinedBehaviorSanitizer.
In addition to ``-fsanitize=``, pass one of the following compile-time flags:
* ``-fsanitize-coverage=func`` for function-level coverage (very fast).
* ``-fsanitize-coverage=bb`` for basic-block-level coverage (may add up to 30%
**extra** slowdown).
* ``-fsanitize-coverage=edge`` for edge-level coverage (up to 40% slowdown).
You may also specify ``-fsanitize-coverage=indirect-calls`` for
additional `caller-callee coverage`_.
At run time, pass ``coverage=1`` in ``ASAN_OPTIONS``, ``LSAN_OPTIONS``,
``MSAN_OPTIONS`` or ``UBSAN_OPTIONS``, as appropriate.
To get `Coverage counters`_, add ``-fsanitize-coverage=8bit-counters``
to one of the above compile-time flags. At runtime, use
``*SAN_OPTIONS=coverage=1:coverage_counters=1``.
Example:
.. code-block:: console
% cat -n cov.cc
1 #include <stdio.h>
2 __attribute__((noinline))
3 void foo() { printf("foo\n"); }
4
5 int main(int argc, char **argv) {
6 if (argc == 2)
7 foo();
8 printf("main\n");
9 }
% clang++ -g cov.cc -fsanitize=address -fsanitize-coverage=func
% ASAN_OPTIONS=coverage=1 ./a.out; ls -l *sancov
main
-rw-r----- 1 kcc eng 4 Nov 27 12:21 a.out.22673.sancov
% ASAN_OPTIONS=coverage=1 ./a.out foo ; ls -l *sancov
foo
main
-rw-r----- 1 kcc eng 4 Nov 27 12:21 a.out.22673.sancov
-rw-r----- 1 kcc eng 8 Nov 27 12:21 a.out.22679.sancov
Every time you run an executable instrumented with SanitizerCoverage
one ``*.sancov`` file is created during the process shutdown.
If the executable is dynamically linked against instrumented DSOs,
one ``*.sancov`` file will be also created for every DSO.
Postprocessing
==============
The format of ``*.sancov`` files is very simple: the first 8 bytes is the magic,
one of ``0xC0BFFFFFFFFFFF64`` and ``0xC0BFFFFFFFFFFF32``. The last byte of the
magic defines the size of the following offsets. The rest of the data is the
offsets in the corresponding binary/DSO that were executed during the run.
A simple script
``$LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py`` is
provided to dump these offsets.
.. code-block:: console
% sancov.py print a.out.22679.sancov a.out.22673.sancov
sancov.py: read 2 PCs from a.out.22679.sancov
sancov.py: read 1 PCs from a.out.22673.sancov
sancov.py: 2 files merged; 2 PCs total
0x465250
0x4652a0
You can then filter the output of ``sancov.py`` through ``addr2line --exe
ObjectFile`` or ``llvm-symbolizer --obj ObjectFile`` to get file names and line
numbers:
.. code-block:: console
% sancov.py print a.out.22679.sancov a.out.22673.sancov 2> /dev/null | llvm-symbolizer --obj a.out
cov.cc:3
cov.cc:5
How good is the coverage?
=========================
It is possible to find out which PCs are not covered, by subtracting the covered
set from the set of all instrumented PCs. The latter can be obtained by listing
all callsites of ``__sanitizer_cov()`` in the binary. On Linux, ``sancov.py``
can do this for you. Just supply the path to binary and a list of covered PCs:
.. code-block:: console
% sancov.py print a.out.12345.sancov > covered.txt
sancov.py: read 2 64-bit PCs from a.out.12345.sancov
sancov.py: 1 file merged; 2 PCs total
% sancov.py missing a.out < covered.txt
sancov.py: found 3 instrumented PCs in a.out
sancov.py: read 2 PCs from stdin
sancov.py: 1 PCs missing from coverage
0x4cc61c
Edge coverage
=============
Consider this code:
.. code-block:: c++
void foo(int *a) {
if (a)
*a = 0;
}
It contains 3 basic blocks, let's name them A, B, C:
.. code-block:: none
A
|\
| \
| B
| /
|/
C
If blocks A, B, and C are all covered we know for certain that the edges A=>B
and B=>C were executed, but we still don't know if the edge A=>C was executed.
Such edges of control flow graph are called
`critical <http://en.wikipedia.org/wiki/Control_flow_graph#Special_edges>`_. The
edge-level coverage (``-fsanitize-coverage=edge``) simply splits all critical
edges by introducing new dummy blocks and then instruments those blocks:
.. code-block:: none
A
|\
| \
D B
| /
|/
C
Bitset
======
When ``coverage_bitset=1`` run-time flag is given, the coverage will also be
dumped as a bitset (text file with 1 for blocks that have been executed and 0
for blocks that were not).
.. code-block:: console
% clang++ -fsanitize=address -fsanitize-coverage=edge cov.cc
% ASAN_OPTIONS="coverage=1:coverage_bitset=1" ./a.out
main
% ASAN_OPTIONS="coverage=1:coverage_bitset=1" ./a.out 1
foo
main
% head *bitset*
==> a.out.38214.bitset-sancov <==
01101
==> a.out.6128.bitset-sancov <==
11011%
For a given executable the length of the bitset is always the same (well,
unless dlopen/dlclose come into play), so the bitset coverage can be
easily used for bitset-based corpus distillation.
Caller-callee coverage
======================
(Experimental!)
Every indirect function call is instrumented with a run-time function call that
captures caller and callee. At the shutdown time the process dumps a separate
file called ``caller-callee.PID.sancov`` which contains caller/callee pairs as
pairs of lines (odd lines are callers, even lines are callees)
.. code-block:: console
a.out 0x4a2e0c
a.out 0x4a6510
a.out 0x4a2e0c
a.out 0x4a87f0
Current limitations:
* Only the first 14 callees for every caller are recorded, the rest are silently
ignored.
* The output format is not very compact since caller and callee may reside in
different modules and we need to spell out the module names.
* The routine that dumps the output is not optimized for speed
* Only Linux x86_64 is tested so far.
* Sandboxes are not supported.
Coverage counters
=================
This experimental feature is inspired by
`AFL <http://lcamtuf.coredump.cx/afl/technical_details.txt>`_'s coverage
instrumentation. With additional compile-time and run-time flags you can get
more sensitive coverage information. In addition to boolean values assigned to
every basic block (edge) the instrumentation will collect imprecise counters.
On exit, every counter will be mapped to a 8-bit bitset representing counter
ranges: ``1, 2, 3, 4-7, 8-15, 16-31, 32-127, 128+`` and those 8-bit bitsets will
be dumped to disk.
.. code-block:: console
% clang++ -g cov.cc -fsanitize=address -fsanitize-coverage=edge,8bit-counters
% ASAN_OPTIONS="coverage=1:coverage_counters=1" ./a.out
% ls -l *counters-sancov
... a.out.17110.counters-sancov
% xxd *counters-sancov
0000000: 0001 0100 01
These counters may also be used for in-process coverage-guided fuzzers. See
``include/sanitizer/coverage_interface.h``:
.. code-block:: c++
// The coverage instrumentation may optionally provide imprecise counters.
// Rather than exposing the counter values to the user we instead map
// the counters to a bitset.
// Every counter is associated with 8 bits in the bitset.
// We define 8 value ranges: 1, 2, 3, 4-7, 8-15, 16-31, 32-127, 128+
// The i-th bit is set to 1 if the counter value is in the i-th range.
// This counter-based coverage implementation is *not* thread-safe.
// Returns the number of registered coverage counters.
uintptr_t __sanitizer_get_number_of_counters();
// Updates the counter 'bitset', clears the counters and returns the number of
// new bits in 'bitset'.
// If 'bitset' is nullptr, only clears the counters.
// Otherwise 'bitset' should be at least
// __sanitizer_get_number_of_counters bytes long and 8-aligned.
uintptr_t
__sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);
Output directory
================
By default, .sancov files are created in the current working directory.
This can be changed with ``ASAN_OPTIONS=coverage_dir=/path``:
.. code-block:: console
% ASAN_OPTIONS="coverage=1:coverage_dir=/tmp/cov" ./a.out foo
% ls -l /tmp/cov/*sancov
-rw-r----- 1 kcc eng 4 Nov 27 12:21 a.out.22673.sancov
-rw-r----- 1 kcc eng 8 Nov 27 12:21 a.out.22679.sancov
Sudden death
============
Normally, coverage data is collected in memory and saved to disk when the
program exits (with an ``atexit()`` handler), when a SIGSEGV is caught, or when
``__sanitizer_cov_dump()`` is called.
If the program ends with a signal that ASan does not handle (or can not handle
at all, like SIGKILL), coverage data will be lost. This is a big problem on
Android, where SIGKILL is a normal way of evicting applications from memory.
With ``ASAN_OPTIONS=coverage=1:coverage_direct=1`` coverage data is written to a
memory-mapped file as soon as it collected.
.. code-block:: console
% ASAN_OPTIONS="coverage=1:coverage_direct=1" ./a.out
main
% ls
7036.sancov.map 7036.sancov.raw a.out
% sancov.py rawunpack 7036.sancov.raw
sancov.py: reading map 7036.sancov.map
sancov.py: unpacking 7036.sancov.raw
writing 1 PCs to a.out.7036.sancov
% sancov.py print a.out.7036.sancov
sancov.py: read 1 PCs from a.out.7036.sancov
sancov.py: 1 files merged; 1 PCs total
0x4b2bae
Note that on 64-bit platforms, this method writes 2x more data than the default,
because it stores full PC values instead of 32-bit offsets.
In-process fuzzing
==================
Coverage data could be useful for fuzzers and sometimes it is preferable to run
a fuzzer in the same process as the code being fuzzed (in-process fuzzer).
You can use ``__sanitizer_get_total_unique_coverage()`` from
``<sanitizer/coverage_interface.h>`` which returns the number of currently
covered entities in the program. This will tell the fuzzer if the coverage has
increased after testing every new input.
If a fuzzer finds a bug in the ASan run, you will need to save the reproducer
before exiting the process. Use ``__asan_set_death_callback`` from
``<sanitizer/asan_interface.h>`` to do that.
An example of such fuzzer can be found in `the LLVM tree
<http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/README.txt?view=markup>`_.
Performance
===========
This coverage implementation is **fast**. With function-level coverage
(``-fsanitize-coverage=func``) the overhead is not measurable. With
basic-block-level coverage (``-fsanitize-coverage=bb``) the overhead varies
between 0 and 25%.
============== ========= ========= ========= ========= ========= =========
benchmark cov0 cov1 diff 0-1 cov2 diff 0-2 diff 1-2
============== ========= ========= ========= ========= ========= =========
400.perlbench 1296.00 1307.00 1.01 1465.00 1.13 1.12
401.bzip2 858.00 854.00 1.00 1010.00 1.18 1.18
403.gcc 613.00 617.00 1.01 683.00 1.11 1.11
429.mcf 605.00 582.00 0.96 610.00 1.01 1.05
445.gobmk 896.00 880.00 0.98 1050.00 1.17 1.19
456.hmmer 892.00 892.00 1.00 918.00 1.03 1.03
458.sjeng 995.00 1009.00 1.01 1217.00 1.22 1.21
462.libquantum 497.00 492.00 0.99 534.00 1.07 1.09
464.h264ref 1461.00 1467.00 1.00 1543.00 1.06 1.05
471.omnetpp 575.00 590.00 1.03 660.00 1.15 1.12
473.astar 658.00 652.00 0.99 715.00 1.09 1.10
483.xalancbmk 471.00 491.00 1.04 582.00 1.24 1.19
433.milc 616.00 627.00 1.02 627.00 1.02 1.00
444.namd 602.00 601.00 1.00 654.00 1.09 1.09
447.dealII 630.00 634.00 1.01 653.00 1.04 1.03
450.soplex 365.00 368.00 1.01 395.00 1.08 1.07
453.povray 427.00 434.00 1.02 495.00 1.16 1.14
470.lbm 357.00 375.00 1.05 370.00 1.04 0.99
482.sphinx3 927.00 928.00 1.00 1000.00 1.08 1.08
============== ========= ========= ========= ========= ========= =========
Why another coverage?
=====================
Why did we implement yet another code coverage?
* We needed something that is lightning fast, plays well with
AddressSanitizer, and does not significantly increase the binary size.
* Traditional coverage implementations based in global counters
`suffer from contention on counters
<https://groups.google.com/forum/#!topic/llvm-dev/cDqYgnxNEhY>`_.

Просмотреть файл

@ -857,6 +857,9 @@ implementation.
// Assert that is mutex is currently held for read operations.
void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this);
// For negative capabilities.
const Mutex& operator!() const { return *this; }
};

Просмотреть файл

@ -589,6 +589,25 @@ Current limitations
translated from debug annotations. That translation can be lossy,
which results in some remarks having no location information.
Other Options
-------------
Clang options that that don't fit neatly into other categories.
.. option:: -MV
When emitting a dependency file, use formatting conventions appropriate
for NMake or Jom. Ignored unless another option causes Clang to emit a
dependency file.
When Clang emits a dependency file (e.g., you supplied the -M option)
most filenames can be written to the file without any special formatting.
Different Make tools will treat different sets of characters as "special"
and use different conventions for telling the Make tool that the character
is actually part of the filename. Normally Clang uses backslash to "escape"
a special character, which is the convention used by GNU Make. The -MV
option tells Clang to put double-quotes around the entire filename, which
is the convention used by NMake and Jom.
Language and Target-Independent Features
========================================
@ -911,6 +930,8 @@ number of cases where the compilation environment is tightly controlled
and the precompiled header cannot be generated after headers have been
installed.
.. _controlling-code-generation:
Controlling Code Generation
---------------------------
@ -959,6 +980,8 @@ are listed below.
flow analysis.
- ``-fsanitize=cfi``: :doc:`control flow integrity <ControlFlowIntegrity>`
checks. Implies ``-flto``.
- ``-fsanitize=safe-stack``: :doc:`safe stack <SafeStack>`
protection against stack-based memory corruption errors.
The following more fine-grained checks are also available:
@ -1078,6 +1101,11 @@ are listed below.
sanitizers (e.g. :doc:`AddressSanitizer`) may not support recovery,
and always crash the program after the issue is detected.
**-f[no-]sanitize-coverage=[type,features,...]**
Enable simple code coverage in addition to certain sanitizers.
See :doc:`SanitizerCoverage` for more details.
.. option:: -fno-assume-sane-operator-new
Don't assume that the C++'s new operator is sane.
@ -1190,6 +1218,32 @@ behavior. Code that is not exercised in the profile will be optimized as if it
is unimportant, and the compiler may make poor optimization choices for code
that is disproportionately used while profiling.
Differences Between Sampling and Instrumentation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Although both techniques are used for similar purposes, there are important
differences between the two:
1. Profile data generated with one cannot be used by the other, and there is no
conversion tool that can convert one to the other. So, a profile generated
via ``-fprofile-instr-generate`` must be used with ``-fprofile-instr-use``.
Similarly, sampling profiles generated by external profilers must be
converted and used with ``-fprofile-sample-use``.
2. Instrumentation profile data can be used for code coverage analysis and
optimization.
3. Sampling profiles can only be used for optimization. They cannot be used for
code coverage analysis. Although it would be technically possible to use
sampling profiles for code coverage, sample-based profiles are too
coarse-grained for code coverage purposes; it would yield poor results.
4. Sampling profiles must be generated by an external tool. The profile
generated by that tool must then be converted into a format that can be read
by LLVM. The section on sampling profilers describes one of the supported
sampling profile formats.
Using Sampling Profilers
^^^^^^^^^^^^^^^^^^^^^^^^
@ -1257,17 +1311,38 @@ usual build cycle when using sample profilers for optimization:
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code
Sample Profile Format
"""""""""""""""""""""
Sample Profile Formats
""""""""""""""""""""""
If you are not using Linux Perf to collect profiles, you will need to
write a conversion tool from your profiler to LLVM's format. This section
explains the file format expected by the backend.
Since external profilers generate profile data in a variety of custom formats,
the data generated by the profiler must be converted into a format that can be
read by the backend. LLVM supports three different sample profile formats:
Sample profiles are written as ASCII text. The file is divided into sections,
which correspond to each of the functions executed at runtime. Each
section has the following format (taken from
https://github.com/google/autofdo/blob/master/profile_writer.h):
1. ASCII text. This is the easiest one to generate. The file is divided into
sections, which correspond to each of the functions with profile
information. The format is described below.
2. Binary encoding. This uses a more efficient encoding that yields smaller
profile files, which may be useful when generating large profiles. It can be
generated from the text format using the ``llvm-profdata`` tool.
3. GCC encoding. This is based on the gcov format, which is accepted by GCC. It
is only interesting in environments where GCC and Clang co-exist. Similarly
to the binary encoding, it can be generated using the ``llvm-profdata`` tool.
If you are using Linux Perf to generate sampling profiles, you can use the
conversion tool ``create_llvm_prof`` described in the previous section.
Otherwise, you will need to write a conversion tool that converts your
profiler's native format into one of these three.
Sample Profile Text Format
""""""""""""""""""""""""""
This section describes the ASCII text format for sampling profiles. It is,
arguably, the easiest one to generate. If you are interested in generating any
of the other two, consult the ``ProfileData`` library in in LLVM's source tree
(specifically, ``llvm/lib/ProfileData/SampleProfWriter.cpp``).
.. code-block:: console
@ -1374,8 +1449,8 @@ instrumentation:
$ LLVM_PROFILE_FILE="code-%p.profraw" ./code
3. Combine profiles from multiple runs and convert the "raw" profile format to
the input expected by clang. Use the ``merge`` command of the llvm-profdata
tool to do this.
the input expected by clang. Use the ``merge`` command of the
``llvm-profdata`` tool to do this.
.. code-block:: console

Просмотреть файл

@ -26,8 +26,10 @@ Using Clang as a Compiler
MemorySanitizer
DataFlowSanitizer
LeakSanitizer
SanitizerCoverage
SanitizerSpecialCaseList
ControlFlowIntegrity
SafeStack
Modules
MSVCCompatibility
FAQ

Просмотреть файл

@ -39,12 +39,12 @@ the other tools.
This stage handles tokenization of the input source file, macro expansion,
#include expansion and handling of other preprocessor directives. The output of
this stage is typically called a ".i" (for C), ".ii" (for C++), ".mi" (for
Objective-C) , or ".mii" (for Objective-C++) file.
Objective-C), or ".mii" (for Objective-C++) file.
=item B<Parsing and Semantic Analysis>
This stage parses the input file, translating preprocessor tokens into a parse
tree. Once in the form of a parser tree, it applies semantic analysis to compute
tree. Once in the form of a parse tree, it applies semantic analysis to compute
types for expressions as well and determine whether the code is well formed. This
stage is responsible for generating most of the compiler warnings as well as
parse errors. The output of this stage is an "Abstract Syntax Tree" (AST).
@ -330,13 +330,13 @@ all by the program.
=item B<-fexceptions>
Enable generation of unwind information, this allows exceptions to be thrown
Enable generation of unwind information. This allows exceptions to be thrown
through Clang compiled stack frames. This is on by default in x86-64.
=item B<-ftrapv>
Generate code to catch integer overflow errors. Signed integer overflow is
undefined in C, with this flag, extra code is generated to detect this and abort
undefined in C. With this flag, extra code is generated to detect this and abort
when it happens.
@ -389,7 +389,7 @@ Display available options.
=item B<-Qunused-arguments>
Don't emit warning for unused driver arguments.
Do not emit any warnings for unused driver arguments.
=item B<-Wa,>I<args>
@ -578,7 +578,7 @@ write temporary files used during the compilation process.
If this environment variable is present, it is treated as a delimited
list of paths to be added to the default system include path list. The
delimiter is the platform dependent delimitor, as used in the I<PATH>
delimiter is the platform dependent delimiter, as used in the I<PATH>
environment variable.
Empty components in the environment variable are ignored.
@ -592,7 +592,7 @@ which are only used when processing the appropriate language.
=item B<MACOSX_DEPLOYMENT_TARGET>
If -mmacosx-version-min is unspecified, the default deployment target
is read from this environment variable. This option only affects darwin
is read from this environment variable. This option only affects Darwin
targets.
=back

Просмотреть файл

@ -15,14 +15,23 @@
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Sema/Sema.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
namespace {
class PrintFunctionsConsumer : public ASTConsumer {
CompilerInstance &Instance;
std::set<std::string> ParsedTemplates;
public:
PrintFunctionsConsumer(CompilerInstance &Instance,
std::set<std::string> ParsedTemplates)
: Instance(Instance), ParsedTemplates(ParsedTemplates) {}
bool HandleTopLevelDecl(DeclGroupRef DG) override {
for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) {
const Decl *D = *i;
@ -32,13 +41,47 @@ public:
return true;
}
void HandleTranslationUnit(ASTContext& context) override {
if (!Instance.getLangOpts().DelayedTemplateParsing)
return;
// This demonstrates how to force instantiation of some templates in
// -fdelayed-template-parsing mode. (Note: Doing this unconditionally for
// all templates is similar to not using -fdelayed-template-parsig in the
// first place.)
// The advantage of doing this in HandleTranslationUnit() is that all
// codegen (when using -add-plugin) is completely finished and this can't
// affect the compiler output.
struct Visitor : public RecursiveASTVisitor<Visitor> {
const std::set<std::string> &ParsedTemplates;
Visitor(const std::set<std::string> &ParsedTemplates)
: ParsedTemplates(ParsedTemplates) {}
bool VisitFunctionDecl(FunctionDecl *FD) {
if (FD->isLateTemplateParsed() &&
ParsedTemplates.count(FD->getNameAsString()))
LateParsedDecls.insert(FD);
return true;
}
std::set<FunctionDecl*> LateParsedDecls;
} v(ParsedTemplates);
v.TraverseDecl(context.getTranslationUnitDecl());
clang::Sema &sema = Instance.getSema();
for (const FunctionDecl *FD : v.LateParsedDecls) {
clang::LateParsedTemplate* LPT = sema.LateParsedTemplateMap.lookup(FD);
sema.LateTemplateParser(sema.OpaqueParser, *LPT);
llvm::errs() << "late-parsed-decl: \"" << FD->getNameAsString() << "\"\n";
}
}
};
class PrintFunctionNamesAction : public PluginASTAction {
std::set<std::string> ParsedTemplates;
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef) override {
return llvm::make_unique<PrintFunctionsConsumer>();
return llvm::make_unique<PrintFunctionsConsumer>(CI, ParsedTemplates);
}
bool ParseArgs(const CompilerInstance &CI,
@ -47,12 +90,20 @@ protected:
llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
// Example error handling.
DiagnosticsEngine &D = CI.getDiagnostics();
if (args[i] == "-an-error") {
DiagnosticsEngine &D = CI.getDiagnostics();
unsigned DiagID = D.getCustomDiagID(DiagnosticsEngine::Error,
"invalid argument '%0'");
D.Report(DiagID) << args[i];
return false;
} else if (args[i] == "-parse-template") {
if (i + 1 >= e) {
D.Report(D.getCustomDiagID(DiagnosticsEngine::Error,
"missing -parse-template argument"));
return false;
}
++i;
ParsedTemplates.insert(args[i]);
}
}
if (!args.empty() && args[0] == "help")

Просмотреть файл

@ -5736,9 +5736,6 @@ CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T,
* @}
*/
/* Include the comment API for compatibility. This will eventually go away. */
#include "clang-c/Documentation.h"
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -284,6 +284,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// merged into.
llvm::DenseMap<Decl*, Decl*> MergedDecls;
/// \brief A mapping from a defining declaration to a list of modules (other
/// than the owning module of the declaration) that contain merged
/// definitions of that entity.
llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
public:
/// \brief A type synonym for the TemplateOrInstantiation mapping.
typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
@ -781,6 +786,23 @@ public:
MergedDecls[D] = Primary;
}
/// \brief Note that the definition \p ND has been merged into module \p M,
/// and should be visible whenever \p M is visible.
void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
bool NotifyListeners = true);
/// \brief Clean up the merged definition list. Call this if you might have
/// added duplicates into the list.
void deduplicateMergedDefinitonsFor(NamedDecl *ND);
/// \brief Get the additional modules in which the definition \p Def has
/// been merged.
ArrayRef<Module*> getModulesWithMergedDefinition(NamedDecl *Def) {
auto MergedIt = MergedDefModules.find(Def);
if (MergedIt == MergedDefModules.end())
return None;
return MergedIt->second;
}
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
ExternCContextDecl *getExternCContextDecl() const;
@ -1691,6 +1713,10 @@ public:
/// beneficial for performance to overalign a data type.
unsigned getPreferredTypeAlign(const Type *T) const;
/// \brief Return the default alignment for __attribute__((aligned)) on
/// this target, to be used if no alignment value is specified.
unsigned getTargetDefaultAlignForAttributeAligned(void) const;
/// \brief Return the alignment in bits that should be given to a
/// global variable with type \p T.
unsigned getAlignOfGlobalVar(QualType T) const;

Просмотреть файл

@ -121,6 +121,11 @@ namespace clang {
/// if an error occurred.
Decl *Import(Decl *FromD);
/// \brief Return the copy of the given declaration in the "to" context if
/// it has already been imported from the "from" context. Otherwise return
/// NULL.
Decl *GetAlreadyImportedOrNull(Decl *FromD);
/// \brief Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///

Просмотреть файл

@ -13,8 +13,6 @@
#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
#include "clang/Basic/SourceLocation.h"
namespace clang {
class ClassTemplateDecl;
class ClassTemplateSpecializationDecl;
@ -24,6 +22,7 @@ namespace clang {
class DeclContext;
class FunctionDecl;
class FunctionTemplateDecl;
class Module;
class NamedDecl;
class ObjCCategoryDecl;
class ObjCContainerDecl;
@ -117,8 +116,9 @@ public:
/// \brief A definition has been made visible by being redefined locally.
///
/// \param D The definition that was previously not visible.
virtual void RedefinedHiddenDefinition(const NamedDecl *D,
SourceLocation Loc) {}
/// \param M The containing module in which the definition was made visible,
/// if any.
virtual void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {}
// NOTE: If new methods are added they should also be added to
// MultiplexASTMutationListener.

Просмотреть файл

@ -20,6 +20,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/SmallVector.h"

Просмотреть файл

@ -333,12 +333,12 @@ public:
/// struct D : B, C { };
/// \endcode
///
/// This data structure contaings a mapping from every virtual
/// This data structure contains a mapping from every virtual
/// function *that does not override an existing virtual function* and
/// in every subobject where that virtual function occurs to the set
/// of virtual functions that override it. Thus, the same virtual
/// function \c A::f can actually occur in multiple subobjects of type
/// \c A due to multiple inheritance, and may be overriden by
/// \c A due to multiple inheritance, and may be overridden by
/// different virtual functions in each, as in the following example:
///
/// \code
@ -354,7 +354,7 @@ public:
/// \c A::f but in *different* subobjects of type A. This is
/// represented by numbering the subobjects in which the overridden
/// and the overriding virtual member functions are located. Subobject
/// 0 represents the virtua base class subobject of that type, while
/// 0 represents the virtual base class subobject of that type, while
/// subobject numbers greater than 0 refer to non-virtual base class
/// subobjects of that type.
class CXXFinalOverriderMap

Просмотреть файл

@ -75,11 +75,7 @@ class Parser {
return;
MoreLATokens.push_back(Tok);
for (const Token *I = &Toks.back(),
*B = &Toks.front();
I != B; --I) {
MoreLATokens.push_back(*I);
}
MoreLATokens.append(Toks.rbegin(), std::prev(Toks.rend()));
Tok = Toks[0];
}

Просмотреть файл

@ -531,10 +531,7 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
}
}
for (SmallVectorImpl<Stmt *>::reverse_iterator RI = StmtsToEnqueue.rbegin(),
RE = StmtsToEnqueue.rend();
RI != RE; ++RI)
Queue.push_back(*RI);
Queue.append(StmtsToEnqueue.rbegin(), StmtsToEnqueue.rend());
}
return true;
@ -791,7 +788,7 @@ template <typename Derived>
bool
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C) {
if (C->isInitCapture())
if (LE->isInitCapture(C))
TRY_TO(TraverseDecl(C->getCapturedVar()));
return true;
}
@ -2204,9 +2201,11 @@ DEF_TRAVERSE_STMT(CXXThisExpr, {})
DEF_TRAVERSE_STMT(CXXThrowExpr, {})
DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
DEF_TRAVERSE_STMT(NoInitExpr, {})
DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
@ -2435,6 +2434,7 @@ template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
TRY_TO(TraverseStmt(C->getChunkSize()));
TRY_TO(TraverseStmt(C->getHelperChunkSize()));
return true;
}

Просмотреть файл

@ -39,6 +39,7 @@ class LabelStmt;
class MemberSpecializationInfo;
class Module;
class NestedNameSpecifier;
class ParmVarDecl;
class Stmt;
class StringLiteral;
class TemplateArgumentList;
@ -82,10 +83,7 @@ class TranslationUnitDecl : public Decl, public DeclContext {
/// translation unit, if one has been created.
NamespaceDecl *AnonymousNamespace;
explicit TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, nullptr, SourceLocation()),
DeclContext(TranslationUnit),
Ctx(ctx), AnonymousNamespace(nullptr) {}
explicit TranslationUnitDecl(ASTContext &ctx);
public:
ASTContext &getASTContext() const { return Ctx; }
@ -238,7 +236,11 @@ public:
bool isHidden() const { return Hidden; }
/// \brief Set whether this declaration is hidden from name lookup.
void setHidden(bool Hide) { Hidden = Hide; }
void setHidden(bool Hide) {
assert((!Hide || isFromASTFile() || hasLocalOwningModuleStorage()) &&
"declaration with no owning module can't be hidden");
Hidden = Hide;
}
/// \brief Determine whether this declaration is a C++ class member.
bool isCXXClassMember() const {
@ -750,37 +752,8 @@ private:
unsigned SClass : 3;
unsigned TSCSpec : 2;
unsigned InitStyle : 2;
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
/// \brief Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization
/// (NRVO).
unsigned NRVOVariable : 1;
/// \brief Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
unsigned CXXForRangeDecl : 1;
/// \brief Whether this variable is an ARC pseudo-__strong
/// variable; see isARCPseudoStrong() for details.
unsigned ARCPseudoStrong : 1;
/// \brief Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
/// \brief Whether this variable is the implicit variable for a lambda
/// init-capture.
unsigned IsInitCapture : 1;
/// \brief Whether this local extern variable's previous declaration was
/// declared in the same block scope. This controls whether we should merge
/// the type of this declaration with its previous declaration.
unsigned PreviousDeclInSameBlockScope : 1;
};
enum { NumVarDeclBits = 14 };
enum { NumVarDeclBits = 7 };
friend class ASTDeclReader;
friend class StmtIteratorBase;
@ -816,10 +789,47 @@ protected:
unsigned ParameterIndex : NumParameterIndexBits;
};
class NonParmVarDeclBitfields {
friend class VarDecl;
friend class ASTDeclReader;
unsigned : NumVarDeclBits;
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
/// \brief Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization
/// (NRVO).
unsigned NRVOVariable : 1;
/// \brief Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
unsigned CXXForRangeDecl : 1;
/// \brief Whether this variable is an ARC pseudo-__strong
/// variable; see isARCPseudoStrong() for details.
unsigned ARCPseudoStrong : 1;
/// \brief Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
/// \brief Whether this variable is the implicit variable for a lambda
/// init-capture.
unsigned IsInitCapture : 1;
/// \brief Whether this local extern variable's previous declaration was
/// declared in the same block scope. This controls whether we should merge
/// the type of this declaration with its previous declaration.
unsigned PreviousDeclInSameBlockScope : 1;
};
union {
unsigned AllBits;
VarDeclBitfields VarDeclBits;
ParmVarDeclBitfields ParmVarDeclBits;
NonParmVarDeclBitfields NonParmVarDeclBits;
};
VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
@ -1172,9 +1182,12 @@ public:
/// \brief Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C \@catch statement.
bool isExceptionVariable() const {
return VarDeclBits.ExceptionVar;
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar;
}
void setExceptionVariable(bool EV) {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.ExceptionVar = EV;
}
void setExceptionVariable(bool EV) { VarDeclBits.ExceptionVar = EV; }
/// \brief Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
@ -1186,36 +1199,64 @@ public:
/// return slot when returning from the function. Within the function body,
/// each return that returns the NRVO object will have this variable as its
/// NRVO candidate.
bool isNRVOVariable() const { return VarDeclBits.NRVOVariable; }
void setNRVOVariable(bool NRVO) { VarDeclBits.NRVOVariable = NRVO; }
bool isNRVOVariable() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable;
}
void setNRVOVariable(bool NRVO) {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.NRVOVariable = NRVO;
}
/// \brief Determine whether this variable is the for-range-declaration in
/// a C++0x for-range statement.
bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; }
void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; }
bool isCXXForRangeDecl() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl;
}
void setCXXForRangeDecl(bool FRD) {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.CXXForRangeDecl = FRD;
}
/// \brief Determine whether this variable is an ARC pseudo-__strong
/// variable. A pseudo-__strong variable has a __strong-qualified
/// type but does not actually retain the object written into it.
/// Generally such variables are also 'const' for safety.
bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; }
bool isARCPseudoStrong() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ARCPseudoStrong;
}
void setARCPseudoStrong(bool ps) {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.ARCPseudoStrong = ps;
}
/// Whether this variable is (C++11) constexpr.
bool isConstexpr() const { return VarDeclBits.IsConstexpr; }
void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; }
bool isConstexpr() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr;
}
void setConstexpr(bool IC) {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.IsConstexpr = IC;
}
/// Whether this variable is the implicit variable for a lambda init-capture.
bool isInitCapture() const { return VarDeclBits.IsInitCapture; }
void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; }
bool isInitCapture() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
}
void setInitCapture(bool IC) {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.IsInitCapture = IC;
}
/// Whether this local extern variable declaration's previous declaration
/// was declared in the same block scope. Only correct in C++.
bool isPreviousDeclInSameBlockScope() const {
return VarDeclBits.PreviousDeclInSameBlockScope;
return isa<ParmVarDecl>(this)
? false
: NonParmVarDeclBits.PreviousDeclInSameBlockScope;
}
void setPreviousDeclInSameBlockScope(bool Same) {
VarDeclBits.PreviousDeclInSameBlockScope = Same;
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
}
/// \brief If this variable is an instantiated static data member of a
@ -1889,8 +1930,10 @@ public:
void setPreviousDeclaration(FunctionDecl * PrevDecl);
virtual const FunctionDecl *getCanonicalDecl() const;
FunctionDecl *getCanonicalDecl() override;
const FunctionDecl *getCanonicalDecl() const {
return const_cast<FunctionDecl*>(this)->getCanonicalDecl();
}
unsigned getBuiltinID() const;
@ -2588,7 +2631,10 @@ public:
/// Retrieves the tag declaration for which this is the typedef name for
/// linkage purposes, if any.
TagDecl *getAnonDeclWithTypedefName() const;
///
/// \param AnyRedecl Look for the tag declaration in any redeclaration of
/// this typedef declaration.
TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }

Просмотреть файл

@ -317,7 +317,7 @@ protected:
: NextInContextAndBits(), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), FromASTFile(0), Hidden(0),
Access(AS_none), FromASTFile(0), Hidden(DC && cast<Decl>(DC)->Hidden),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(0)
{
@ -637,15 +637,32 @@ public:
private:
Module *getOwningModuleSlow() const;
protected:
bool hasLocalOwningModuleStorage() const;
public:
Module *getOwningModule() const {
/// \brief Get the imported owning module, if this decl is from an imported
/// (non-local) module.
Module *getImportedOwningModule() const {
if (!isFromASTFile())
return nullptr;
return getOwningModuleSlow();
}
/// \brief Get the local owning module, if known. Returns nullptr if owner is
/// not yet known or declaration is not from a module.
Module *getLocalOwningModule() const {
if (isFromASTFile() || !Hidden)
return nullptr;
return reinterpret_cast<Module *const *>(this)[-1];
}
void setLocalOwningModule(Module *M) {
assert(!isFromASTFile() && Hidden && hasLocalOwningModuleStorage() &&
"should not have a cached owning module");
reinterpret_cast<Module **>(this)[-1] = M;
}
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}

Просмотреть файл

@ -651,8 +651,8 @@ public:
CXXRecordDecl *getCanonicalDecl() override {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
virtual const CXXRecordDecl *getCanonicalDecl() const {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
const CXXRecordDecl *getCanonicalDecl() const {
return const_cast<CXXRecordDecl*>(this)->getCanonicalDecl();
}
CXXRecordDecl *getPreviousDecl() {
@ -1392,6 +1392,10 @@ public:
/// \brief Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
/// \brief Returns true if the class destructor, or any implicitly invoked
/// destructors are marked noreturn.
bool isAnyDestructorNoReturn() const;
/// \brief If the class is a local class [class.local], returns
/// the enclosing function declaration.
const FunctionDecl *isLocalClass() const {
@ -1436,7 +1440,7 @@ public:
///
/// \returns true if this class is derived from \p Base, false otherwise.
///
/// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
/// \todo add a separate parameter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
@ -1781,7 +1785,7 @@ public:
CXXMethodDecl *getCanonicalDecl() override {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
const CXXMethodDecl *getCanonicalDecl() const override {
const CXXMethodDecl *getCanonicalDecl() const {
return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
}
@ -2084,7 +2088,7 @@ public:
/// This can only be called once for each initializer; it cannot be called
/// on an initializer having a positive number of (implicit) array indices.
///
/// This assumes that the initialzier was written in the source code, and
/// This assumes that the initializer was written in the source code, and
/// ensures that isWritten() returns true.
void setSourceOrder(int pos) {
assert(!IsWritten &&
@ -2326,12 +2330,12 @@ public:
/// \brief Set the constructor that this inheriting constructor is based on.
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
const CXXConstructorDecl *getCanonicalDecl() const override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
CXXConstructorDecl *getCanonicalDecl() override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
const CXXConstructorDecl *getCanonicalDecl() const {
return const_cast<CXXConstructorDecl*>(this)->getCanonicalDecl();
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }

Просмотреть файл

@ -217,6 +217,88 @@ public:
}
};
void *allocateDefaultArgStorageChain(const ASTContext &C);
/// Storage for a default argument. This is conceptually either empty, or an
/// argument value, or a pointer to a previous declaration that had a default
/// argument.
///
/// However, this is complicated by modules: while we require all the default
/// arguments for a template to be equivalent, there may be more than one, and
/// we need to track all the originating parameters to determine if the default
/// argument is visible.
template<typename ParmDecl, typename ArgType>
class DefaultArgStorage {
/// Storage for both the value *and* another parameter from which we inherit
/// the default argument. This is used when multiple default arguments for a
/// parameter are merged together from different modules.
struct Chain {
ParmDecl *PrevDeclWithDefaultArg;
ArgType Value;
};
static_assert(sizeof(Chain) == sizeof(void *) * 2,
"non-pointer argument type?");
llvm::PointerUnion3<ArgType, ParmDecl*, Chain*> ValueOrInherited;
static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl*>())
Parm = Prev;
assert(!Parm->getDefaultArgStorage()
.ValueOrInherited.template is<ParmDecl *>() &&
"should only be one level of indirection");
return Parm;
}
public:
DefaultArgStorage() : ValueOrInherited(ArgType()) {}
/// Determine whether there is a default argument for this parameter.
bool isSet() const { return !ValueOrInherited.isNull(); }
/// Determine whether the default argument for this parameter was inherited
/// from a previous declaration of the same entity.
bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
/// Get the default argument's value. This does not consider whether the
/// default argument is visible.
ArgType get() const {
const DefaultArgStorage *Storage = this;
if (auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl*>())
Storage = &Prev->getDefaultArgStorage();
if (auto *C = Storage->ValueOrInherited.template dyn_cast<Chain*>())
return C->Value;
return Storage->ValueOrInherited.template get<ArgType>();
}
/// Get the parameter from which we inherit the default argument, if any.
/// This is the parameter on which the default argument was actually written.
const ParmDecl *getInheritedFrom() const {
if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl*>())
return D;
if (auto *C = ValueOrInherited.template dyn_cast<Chain*>())
return C->PrevDeclWithDefaultArg;
return nullptr;
}
/// Set the default argument.
void set(ArgType Arg) {
assert(!isSet() && "default argument already set");
ValueOrInherited = Arg;
}
/// Set that the default argument was inherited from another parameter.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
assert(!isInherited() && "default argument already inherited");
InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
if (!isSet())
ValueOrInherited = InheritedFrom;
else
ValueOrInherited = new (allocateDefaultArgStorageChain(C))
Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
}
/// Remove the default argument, even if it was inherited.
void clear() {
ValueOrInherited = ArgType();
}
};
//===----------------------------------------------------------------------===//
// Kinds of Templates
//===----------------------------------------------------------------------===//
@ -942,18 +1024,16 @@ class TemplateTypeParmDecl : public TypeDecl {
/// If false, it was declared with the 'class' keyword.
bool Typename : 1;
/// \brief Whether this template type parameter inherited its
/// default argument.
bool InheritedDefault : 1;
/// \brief The default template argument, if any.
TypeSourceInfo *DefaultArgument;
typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>
DefArgStorage;
DefArgStorage DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
bool Typename)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
InheritedDefault(false), DefaultArgument() { }
DefaultArgument() { }
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
@ -974,35 +1054,45 @@ public:
/// If not, it was declared with the 'class' keyword.
bool wasDeclaredWithTypename() const { return Typename; }
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
/// \brief Retrieve the default argument, if any.
QualType getDefaultArgument() const { return DefaultArgument->getType(); }
QualType getDefaultArgument() const {
return DefaultArgument.get()->getType();
}
/// \brief Retrieves the default argument's source information, if any.
TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
TypeSourceInfo *getDefaultArgumentInfo() const {
return DefaultArgument.get();
}
/// \brief Retrieves the location of the default argument declaration.
SourceLocation getDefaultArgumentLoc() const;
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const { return InheritedDefault; }
bool defaultArgumentWasInherited() const {
return DefaultArgument.isInherited();
}
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
DefaultArgument = DefArg;
InheritedDefault = Inherited;
/// \brief Set the default argument for this template parameter.
void setDefaultArgument(TypeSourceInfo *DefArg) {
DefaultArgument.set(DefArg);
}
/// \brief Set that this default argument was inherited from another
/// parameter.
void setInheritedDefaultArgument(const ASTContext &C,
TemplateTypeParmDecl *Prev) {
DefaultArgument.setInherited(C, Prev);
}
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
DefaultArgument = nullptr;
InheritedDefault = false;
DefaultArgument.clear();
}
/// \brief Set whether this template type parameter was declared with
@ -1034,7 +1124,8 @@ class NonTypeTemplateParmDecl
: public DeclaratorDecl, protected TemplateParmPosition {
/// \brief The default template argument, if any, and whether or not
/// it was inherited.
llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
DefArgStorage DefaultArgument;
// FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
// down here to save memory.
@ -1055,9 +1146,8 @@ class NonTypeTemplateParmDecl
IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
ParameterPack(ParameterPack), ExpandedParameterPack(false),
NumExpandedTypes(0)
TemplateParmPosition(D, P), ParameterPack(ParameterPack),
ExpandedParameterPack(false), NumExpandedTypes(0)
{ }
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
@ -1097,16 +1187,14 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
return DefaultArgumentAndInherited.getPointer() != nullptr;
}
bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
/// \brief Retrieve the default argument, if any.
Expr *getDefaultArgument() const {
return DefaultArgumentAndInherited.getPointer();
}
Expr *getDefaultArgument() const { return DefaultArgument.get(); }
/// \brief Retrieve the location of the default argument, if any.
SourceLocation getDefaultArgumentLoc() const;
@ -1114,22 +1202,20 @@ public:
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
return DefaultArgumentAndInherited.getInt();
return DefaultArgument.isInherited();
}
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
void setDefaultArgument(Expr *DefArg, bool Inherited) {
DefaultArgumentAndInherited.setPointer(DefArg);
DefaultArgumentAndInherited.setInt(Inherited);
void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
void setInheritedDefaultArgument(const ASTContext &C,
NonTypeTemplateParmDecl *Parm) {
DefaultArgument.setInherited(C, Parm);
}
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
DefaultArgumentAndInherited.setPointer(nullptr);
DefaultArgumentAndInherited.setInt(false);
}
void removeDefaultArgument() { DefaultArgument.clear(); }
/// \brief Whether this parameter is a non-type template parameter pack.
///
@ -1217,10 +1303,10 @@ class TemplateTemplateParmDecl : public TemplateDecl,
{
void anchor() override;
/// DefaultArgument - The default template argument, if any.
TemplateArgumentLoc DefaultArgument;
/// Whether or not the default argument was inherited.
bool DefaultArgumentWasInherited;
/// \brief The default template argument, if any.
typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>
DefArgStorage;
DefArgStorage DefaultArgument;
/// \brief Whether this parameter is a parameter pack.
bool ParameterPack;
@ -1237,8 +1323,7 @@ class TemplateTemplateParmDecl : public TemplateDecl,
unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
TemplateParmPosition(D, P), DefaultArgument(),
DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
TemplateParmPosition(D, P), ParameterPack(ParameterPack),
ExpandedParameterPack(false), NumExpandedParams(0)
{ }
@ -1322,15 +1407,16 @@ public:
return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
}
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
return !DefaultArgument.getArgument().isNull();
}
bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
/// \brief Retrieve the default argument, if any.
const TemplateArgumentLoc &getDefaultArgument() const {
return DefaultArgument;
static const TemplateArgumentLoc None;
return DefaultArgument.isSet() ? *DefaultArgument.get() : None;
}
/// \brief Retrieve the location of the default argument, if any.
@ -1339,22 +1425,21 @@ public:
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
return DefaultArgumentWasInherited;
return DefaultArgument.isInherited();
}
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
DefaultArgument = DefArg;
DefaultArgumentWasInherited = Inherited;
void setDefaultArgument(const ASTContext &C,
const TemplateArgumentLoc &DefArg);
void setInheritedDefaultArgument(const ASTContext &C,
TemplateTemplateParmDecl *Prev) {
DefaultArgument.setInherited(C, Prev);
}
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
DefaultArgument = TemplateArgumentLoc();
DefaultArgumentWasInherited = false;
}
void removeDefaultArgument() { DefaultArgument.clear(); }
SourceRange getSourceRange() const override LLVM_READONLY {
SourceLocation End = getLocation();

Просмотреть файл

@ -26,29 +26,32 @@ class ASTContext;
/// \brief Given a potentially-evaluated expression, this visitor visits all
/// of its potentially-evaluated subexpressions, recursively.
template<typename ImplClass>
class EvaluatedExprVisitor : public StmtVisitor<ImplClass> {
ASTContext &Context;
template<template <typename> class Ptr, typename ImplClass>
class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
protected:
const ASTContext &Context;
public:
explicit EvaluatedExprVisitor(ASTContext &Context) : Context(Context) { }
#define PTR(CLASS) typename Ptr<CLASS>::type
explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
// Expressions that have no potentially-evaluated subexpressions (but may have
// other sub-expressions).
void VisitDeclRefExpr(DeclRefExpr *E) { }
void VisitOffsetOfExpr(OffsetOfExpr *E) { }
void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
void VisitBlockExpr(BlockExpr *E) { }
void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
void VisitMemberExpr(MemberExpr *E) {
void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
void VisitBlockExpr(PTR(BlockExpr) E) { }
void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
void VisitMemberExpr(PTR(MemberExpr) E) {
// Only the base matters.
return this->Visit(E->getBase());
}
void VisitChooseExpr(ChooseExpr *E) {
void VisitChooseExpr(PTR(ChooseExpr) E) {
// Don't visit either child expression if the condition is dependent.
if (E->getCond()->isValueDependent())
return;
@ -56,7 +59,7 @@ public:
return this->Visit(E->getChosenSubExpr());
}
void VisitGenericSelectionExpr(GenericSelectionExpr *E) {
void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
// The controlling expression of a generic selection is not evaluated.
// Don't visit either child expression if the condition is type-dependent.
@ -67,23 +70,23 @@ public:
return this->Visit(E->getResultExpr());
}
void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
// Only the actual initializer matters; the designators are all constant
// expressions.
return this->Visit(E->getInit());
}
void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
if (E->isPotentiallyEvaluated())
return this->Visit(E->getExprOperand());
}
void VisitCallExpr(CallExpr *CE) {
void VisitCallExpr(PTR(CallExpr) CE) {
if (!CE->isUnevaluatedBuiltinCall(Context))
return static_cast<ImplClass*>(this)->VisitExpr(CE);
}
void VisitLambdaExpr(LambdaExpr *LE) {
void VisitLambdaExpr(PTR(LambdaExpr) LE) {
// Only visit the capture initializers, and not the body.
for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(),
E = LE->capture_init_end();
@ -94,11 +97,31 @@ public:
/// \brief The basis case walks all of the children of the statement or
/// expression, assuming they are all potentially evaluated.
void VisitStmt(Stmt *S) {
for (Stmt::child_range C = S->children(); C; ++C)
void VisitStmt(PTR(Stmt) S) {
for (auto C = S->children(); C; ++C)
if (*C)
this->Visit(*C);
}
#undef PTR
};
/// EvaluatedExprVisitor - This class visits 'Expr *'s
template<typename ImplClass>
class EvaluatedExprVisitor
: public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
public:
explicit EvaluatedExprVisitor(const ASTContext &Context) :
EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
};
/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
template<typename ImplClass>
class ConstEvaluatedExprVisitor
: public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
public:
explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
};
}

Просмотреть файл

@ -276,6 +276,7 @@ public:
MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
MLV_IncompleteType,
MLV_ConstQualified,
MLV_ConstAddrSpace,
MLV_ArrayType,
MLV_NoSetterProperty,
MLV_MemberFunction,
@ -324,6 +325,7 @@ public:
CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
CM_ConstQualified,
CM_ConstAddrSpace,
CM_ArrayType,
CM_IncompleteType
};
@ -596,7 +598,7 @@ public:
/// \brief Determine whether this expression involves a call to any function
/// that is not trivial.
bool hasNonTrivialCall(ASTContext &Ctx);
bool hasNonTrivialCall(const ASTContext &Ctx) const;
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
@ -2271,7 +2273,7 @@ public:
/// \brief Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const;
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
/// getCallReturnType - Get the return type of the call expr. This is not
/// always the type of the expr itself, if the return type is a reference
@ -4265,6 +4267,80 @@ public:
}
};
/// \brief Represents a place-holder for an object not to be initialized by
/// anything.
///
/// This only makes sense when it appears as part of an updater of a
/// DesignatedInitUpdateExpr (see below). The base expression of a DIUE
/// initializes a big object, and the NoInitExpr's mark the spots within the
/// big object not to be overwritten by the updater.
///
/// \see DesignatedInitUpdateExpr
class NoInitExpr : public Expr {
public:
explicit NoInitExpr(QualType ty)
: Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary,
false, false, ty->isInstantiationDependentType(), false) { }
explicit NoInitExpr(EmptyShell Empty)
: Expr(NoInitExprClass, Empty) { }
static bool classof(const Stmt *T) {
return T->getStmtClass() == NoInitExprClass;
}
SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
// Iterators
child_range children() { return child_range(); }
};
// In cases like:
// struct Q { int a, b, c; };
// Q *getQ();
// void foo() {
// struct A { Q q; } a = { *getQ(), .q.b = 3 };
// }
//
// We will have an InitListExpr for a, with type A, and then a
// DesignatedInitUpdateExpr for "a.q" with type Q. The "base" for this DIUE
// is the call expression *getQ(); the "updater" for the DIUE is ".q.b = 3"
//
class DesignatedInitUpdateExpr : public Expr {
// BaseAndUpdaterExprs[0] is the base expression;
// BaseAndUpdaterExprs[1] is an InitListExpr overwriting part of the base.
Stmt *BaseAndUpdaterExprs[2];
public:
DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc,
Expr *baseExprs, SourceLocation rBraceLoc);
explicit DesignatedInitUpdateExpr(EmptyShell Empty)
: Expr(DesignatedInitUpdateExprClass, Empty) { }
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitUpdateExprClass;
}
Expr *getBase() const { return cast<Expr>(BaseAndUpdaterExprs[0]); }
void setBase(Expr *Base) { BaseAndUpdaterExprs[0] = Base; }
InitListExpr *getUpdater() const {
return cast<InitListExpr>(BaseAndUpdaterExprs[1]);
}
void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; }
// Iterators
// children = the base and the updater
child_range children() {
return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
}
};
/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///

Просмотреть файл

@ -1452,6 +1452,9 @@ public:
return CaptureDefaultLoc;
}
/// \brief Determine whether one of this lambda's captures is an init-capture.
bool isInitCapture(const LambdaCapture *Capture) const;
/// \brief An iterator that walks over the captures of the lambda,
/// both implicit and explicit.
typedef const Capture *capture_iterator;

Просмотреть файл

@ -85,11 +85,6 @@ public:
(DeclAndBits.getInt() & Capture_ByCopy);
}
/// \brief Determine whether this is an init-capture.
bool isInitCapture() const {
return capturesVariable() && getCapturedVar()->isInitCapture();
}
/// \brief Retrieve the declaration of the local variable being
/// captured.
///

Просмотреть файл

@ -197,6 +197,10 @@ public:
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
unsigned GuardNum,
raw_ostream &Out) = 0;
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
raw_ostream &) = 0;

Просмотреть файл

@ -216,6 +216,9 @@ public:
/// of that name in objective-c.
StringRef GetNSIntegralKind(QualType T) const;
/// \brief Returns \c true if \p Id is currently defined as a macro.
bool isMacroDefined(StringRef Id) const;
private:
bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
bool isObjCEnumerator(const Expr *E,

Просмотреть файл

@ -573,8 +573,10 @@ class OMPScheduleClause : public OMPClause {
SourceLocation KindLoc;
/// \brief Location of ',' (if any).
SourceLocation CommaLoc;
/// \brief Chunk size.
Stmt *ChunkSize;
/// \brief Chunk size and a reference to pseudo variable for combined
/// directives.
enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS };
Stmt *ChunkSizes[NUM_EXPRS];
/// \brief Set schedule kind.
///
@ -600,7 +602,12 @@ class OMPScheduleClause : public OMPClause {
///
/// \param E Chunk size.
///
void setChunkSize(Expr *E) { ChunkSize = E; }
void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; }
/// \brief Set helper chunk size.
///
/// \param E Helper chunk size.
///
void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; }
public:
/// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
@ -613,19 +620,26 @@ public:
/// \param EndLoc Ending location of the clause.
/// \param Kind Schedule kind.
/// \param ChunkSize Chunk size.
/// \param HelperChunkSize Helper chunk size for combined directives.
///
OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation KLoc, SourceLocation CommaLoc,
SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
Expr *ChunkSize)
Expr *ChunkSize, Expr *HelperChunkSize)
: OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {}
Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) {
ChunkSizes[CHUNK_SIZE] = ChunkSize;
ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize;
}
/// \brief Build an empty clause.
///
explicit OMPScheduleClause()
: OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
Kind(OMPC_SCHEDULE_unknown), ChunkSize(nullptr) {}
Kind(OMPC_SCHEDULE_unknown) {
ChunkSizes[CHUNK_SIZE] = nullptr;
ChunkSizes[HELPER_CHUNK_SIZE] = nullptr;
}
/// \brief Get kind of the clause.
///
@ -641,16 +655,30 @@ public:
SourceLocation getCommaLoc() { return CommaLoc; }
/// \brief Get chunk size.
///
Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSize); }
Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); }
/// \brief Get chunk size.
///
Expr *getChunkSize() const { return dyn_cast_or_null<Expr>(ChunkSize); }
Expr *getChunkSize() const {
return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]);
}
/// \brief Get helper chunk size.
///
Expr *getHelperChunkSize() {
return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]);
}
/// \brief Get helper chunk size.
///
Expr *getHelperChunkSize() const {
return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]);
}
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_schedule;
}
StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); }
StmtRange children() {
return StmtRange(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1);
}
};
/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.

Просмотреть файл

@ -857,7 +857,7 @@ template <typename Derived>
bool
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C) {
if (C->isInitCapture())
if (LE->isInitCapture(C))
TRY_TO(TraverseDecl(C->getCapturedVar()));
return true;
}
@ -2234,9 +2234,11 @@ DEF_TRAVERSE_STMT(CXXThisExpr, {})
DEF_TRAVERSE_STMT(CXXThrowExpr, {})
DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
DEF_TRAVERSE_STMT(NoInitExpr, {})
DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
@ -2465,6 +2467,7 @@ template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
TRY_TO(TraverseStmt(C->getChunkSize()));
TRY_TO(TraverseStmt(C->getHelperChunkSize()));
return true;
}

Просмотреть файл

@ -58,7 +58,9 @@ namespace clang {
class Stmt;
class Expr;
class ExprIterator {
class ExprIterator : public std::iterator<std::forward_iterator_tag,
Expr *&, ptrdiff_t,
Expr *&, Expr *&> {
Stmt** I;
public:
ExprIterator(Stmt** i) : I(i) {}
@ -77,7 +79,10 @@ namespace clang {
bool operator>=(const ExprIterator& R) const { return I >= R.I; }
};
class ConstExprIterator {
class ConstExprIterator : public std::iterator<std::forward_iterator_tag,
const Expr *&, ptrdiff_t,
const Expr *&,
const Expr *&> {
const Stmt * const *I;
public:
ConstExprIterator(const Stmt * const *i) : I(i) {}

Просмотреть файл

@ -108,7 +108,7 @@ public:
typedef const OMPClause *value_type;
filtered_clause_iterator() : Current(), End() {}
filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
: Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
: Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) {
SkipToNextClause();
}
value_type operator*() const { return *Current; }
@ -126,29 +126,24 @@ public:
}
bool operator!() { return Current == End; }
operator bool() { return Current != End; }
explicit operator bool() { return Current != End; }
bool empty() const { return Current == End; }
};
/// \brief A filter to iterate over 'linear' clauses using a C++ range
/// for loop.
struct linear_filter : public filtered_clause_iterator<
std::function<bool(const OMPClause *)> > {
linear_filter(ArrayRef<OMPClause *> Arr)
: filtered_clause_iterator(Arr, [](const OMPClause *C)->bool {
return C->getClauseKind() == OMPC_linear;
}) {}
const OMPLinearClause *operator*() const {
return cast<OMPLinearClause>(*Current);
}
const OMPLinearClause *operator->() const {
return cast<OMPLinearClause>(*Current);
}
friend linear_filter begin(const linear_filter &range) { return range; }
friend linear_filter end(const linear_filter &range) {
return linear_filter(ArrayRef<OMPClause *>(range.End, range.End));
template <typename Fn>
filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const {
return filtered_clause_iterator<Fn>(clauses(), std::move(fn));
}
struct ClauseKindFilter {
OpenMPClauseKind Kind;
bool operator()(const OMPClause *clause) const {
return clause->getClauseKind() == Kind;
}
};
filtered_clause_iterator<ClauseKindFilter>
getClausesOfKind(OpenMPClauseKind Kind) const {
return getFilteredClauses(ClauseKindFilter{Kind});
}
/// \brief Gets a single clause of the specified kind \a K associated with the
/// current directive iff there is only one clause of this kind (and assertion

Просмотреть файл

@ -757,6 +757,15 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl;
/// \brief Matches conversion operator declarations.
///
/// Example matches the operator.
/// \code
/// class X { operator int() const; };
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
conversionDecl;
/// \brief Matches variable declarations.
///
/// Note: this does not match declarations of member variables, which are
@ -1432,6 +1441,11 @@ const internal::VariadicDynCastAllOfMatcher<
Stmt,
CXXNullPtrLiteralExpr> nullPtrLiteralExpr;
/// \brief Matches GNU __null expression.
const internal::VariadicDynCastAllOfMatcher<
Stmt,
GNUNullExpr> gnuNullExpr;
/// \brief Matches binary operator expressions.
///
/// Example matches a || b
@ -1462,6 +1476,23 @@ const internal::VariadicDynCastAllOfMatcher<
Stmt,
ConditionalOperator> conditionalOperator;
/// \brief Matches a C++ static_assert declaration.
///
/// Example:
/// staticAssertExpr()
/// matches
/// static_assert(sizeof(S) == sizeof(int))
/// in
/// \code
/// struct S {
/// int x;
/// };
/// static_assert(sizeof(S) == sizeof(int));
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
StaticAssertDecl> staticAssertDecl;
/// \brief Matches a reinterpret_cast expression.
///
/// Either the source expression or the destination type can be matched
@ -2695,6 +2726,23 @@ AST_MATCHER(FunctionDecl, isDeleted) {
return Node.isDeleted();
}
/// \brief Matches constexpr variable and function declarations.
///
/// Given:
/// \code
/// constexpr int foo = 42;
/// constexpr int bar();
/// \endcode
/// varDecl(isConstexpr())
/// matches the declaration of foo.
/// functionDecl(isConstexpr())
/// matches the declaration of bar.
AST_POLYMORPHIC_MATCHER(isConstexpr,
AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl,
FunctionDecl)) {
return Node.isConstexpr();
}
/// \brief Matches the condition expression of an if statement, for loop,
/// or conditional operator.
///

Просмотреть файл

@ -39,6 +39,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Stmt.h"

Просмотреть файл

@ -657,9 +657,9 @@ public:
bool ParsePrintfString(FormatStringHandler &H,
const char *beg, const char *end, const LangOptions &LO,
const TargetInfo &Target, bool isFreeBSDKPrintf);
bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO,
const TargetInfo &Target);
bool ParseFormatStringHasSArg(const char *beg, const char *end,
const LangOptions &LO, const TargetInfo &Target);
bool ParseScanfString(FormatStringHandler &H,
const char *beg, const char *end, const LangOptions &LO,

Просмотреть файл

@ -738,6 +738,7 @@ public:
bool AddTemporaryDtors;
bool AddStaticInitBranches;
bool AddCXXNewAllocator;
bool AddCXXDefaultInitExprInCtors;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
@ -758,7 +759,7 @@ public:
PruneTriviallyFalseEdges(true), AddEHEdges(false),
AddInitializers(false), AddImplicitDtors(false),
AddTemporaryDtors(false), AddStaticInitBranches(false),
AddCXXNewAllocator(false) {}
AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the

Просмотреть файл

@ -144,6 +144,7 @@ class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
class VariadicExprArgument<string name> : Argument<name, 1>;
class VariadicStringArgument<string name> : Argument<name, 1>;
// A version of the form major.minor[.subminor].
class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
@ -581,7 +582,7 @@ def CUDAInvalidTarget : InheritableAttr {
def CUDALaunchBounds : InheritableAttr {
let Spellings = [GNU<"launch_bounds">];
let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>];
let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
let LangOpts = [CUDA];
let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag,
"ExpectedFunctionOrMethod">;
@ -1249,6 +1250,14 @@ def Pascal : InheritableAttr {
let Documentation = [Undocumented];
}
def Target : InheritableAttr {
let Spellings = [GCC<"target">];
let Args = [StringArgument<"features">];
let Subjects =
SubjectList<[Function], ErrorDiag, "ExpectedFunctionMethodOrClass">;
let Documentation = [Undocumented];
}
def TransparentUnion : InheritableAttr {
let Spellings = [GCC<"transparent_union">];
// let Subjects = SubjectList<[Record, TypedefName]>;
@ -1386,26 +1395,35 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
let Documentation = [Undocumented];
}
// Attribute to disable AddressSanitizer (or equivalent) checks.
def NoSanitizeAddress : InheritableAttr {
def NoSanitize : InheritableAttr {
let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">];
let Args = [VariadicStringArgument<"Sanitizers">];
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
let Documentation = [NoSanitizeDocs];
let AdditionalMembers = [{
SanitizerMask getMask() const {
SanitizerMask Mask = 0;
for (auto SanitizerName : sanitizers()) {
SanitizerMask ParsedMask =
parseSanitizerValue(SanitizerName, /*AllowGroups=*/true);
Mask |= expandSanitizerGroups(ParsedMask);
}
return Mask;
}
}];
}
// Attributes to disable a specific sanitizer. No new sanitizers should be added
// to this list; the no_sanitize attribute should be extended instead.
def NoSanitizeSpecific : InheritableAttr {
let Spellings = [GCC<"no_address_safety_analysis">,
GCC<"no_sanitize_address">];
GCC<"no_sanitize_address">,
GCC<"no_sanitize_thread">,
GNU<"no_sanitize_memory">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeAddressDocs];
}
// Attribute to disable ThreadSanitizer checks.
def NoSanitizeThread : InheritableAttr {
let Spellings = [GNU<"no_sanitize_thread">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeThreadDocs];
}
// Attribute to disable MemorySanitizer checks.
def NoSanitizeMemory : InheritableAttr {
let Spellings = [GNU<"no_sanitize_memory">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeMemoryDocs];
let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
NoSanitizeMemoryDocs];
let ASTNode = 0;
}
// C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
@ -1925,8 +1943,8 @@ def LoopHint : Attr {
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
"Unroll", "UnrollCount"]>,
EnumArgument<"State", "LoopHintState",
["default", "enable", "disable"],
["Default", "Enable", "Disable"]>,
["default", "enable", "disable", "assume_safety"],
["Default", "Enable", "Disable", "AssumeSafety"]>,
ExprArgument<"Value">];
let AdditionalMembers = [{
@ -1972,6 +1990,8 @@ def LoopHint : Attr {
return "";
else if (state == Enable)
OS << (option == Unroll ? "full" : "enable");
else if (state == AssumeSafety)
OS << "assume_safety";
else
OS << "disable";
OS << ")";

Просмотреть файл

@ -920,6 +920,22 @@ This attribute accepts a single parameter that must be one of the following:
}];
}
def NoSanitizeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Use the ``no_sanitize`` attribute on a function declaration to specify
that a particular instrumentation or set of instrumentations should not be
applied to that function. The attribute takes a list of string literals,
which have the same meaning as values accepted by the ``-fno-sanitize=``
flag. For example, ``__attribute__((no_sanitize("address", "thread")))``
specifies that AddressSanitizer and ThreadSanitizer should not be applied
to the function.
See :ref:`Controlling Code Generation <controlling-code-generation>` for a
full list of supported sanitizer flags.
}];
}
def NoSanitizeAddressDocs : Documentation {
let Category = DocCatFunction;
// This function has multiple distinct spellings, and so it requires a custom
@ -936,6 +952,7 @@ not be applied to that function.
def NoSanitizeThreadDocs : Documentation {
let Category = DocCatFunction;
let Heading = "no_sanitize_thread";
let Content = [{
.. _langext-thread_sanitizer:
@ -948,6 +965,7 @@ tool to avoid false positives and provide meaningful stack traces.
def NoSanitizeMemoryDocs : Documentation {
let Category = DocCatFunction;
let Heading = "no_sanitize_memory";
let Content = [{
.. _langext-memory_sanitizer:

Просмотреть файл

@ -1240,6 +1240,10 @@ BUILTIN(__builtin_addressof, "v*v&", "nct")
BUILTIN(__builtin_operator_new, "v*z", "c")
BUILTIN(__builtin_operator_delete, "vv*", "n")
// Safestack builtins
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn")
#undef BUILTIN
#undef LIBBUILTIN
#undef LANGBUILTIN

Просмотреть файл

@ -53,4 +53,12 @@ BUILTIN(__builtin_arm_isb, "vUi", "nc")
// Prefetch
BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
// System Registers
BUILTIN(__builtin_arm_rsr, "UicC*", "nc")
BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc")
BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc")
BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
#undef BUILTIN

Просмотреть файл

@ -84,6 +84,14 @@ BUILTIN(__builtin_arm_isb, "vUi", "nc")
// Prefetch
BUILTIN(__builtin_arm_prefetch, "vvC*UiUi", "nc")
// System registers (ACLE)
BUILTIN(__builtin_arm_rsr, "UicC*", "nc")
BUILTIN(__builtin_arm_rsr64, "LLUicC*", "nc")
BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc")
BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*LLUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
// MSVC
LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES)

Просмотреть файл

@ -26,6 +26,9 @@ BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "")
BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "")
BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi","")
BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "")
@ -33,6 +36,9 @@ BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "")
BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "")
BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi","")
BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "")
@ -103,6 +109,10 @@ BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "")
BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "")
BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "")
BUILTIN(__builtin_altivec_vpksdss, "V4SiV2SLLiV2SLLi", "")
BUILTIN(__builtin_altivec_vpksdus, "V4UiV2SLLiV2SLLi", "")
BUILTIN(__builtin_altivec_vpkudus, "V4UiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vpkudum, "V4UiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "")
@ -194,10 +204,12 @@ BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "")
BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "")
BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "")
BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "")
BUILTIN(__builtin_altivec_vupkhsw, "V2LLiV4i", "")
BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "")
BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "")
BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "")
BUILTIN(__builtin_altivec_vupklsw, "V2LLiV4i", "")
BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
@ -219,6 +231,9 @@ BUILTIN(__builtin_altivec_vcmpgtsd_p, "iiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpgtud_p, "iiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
BUILTIN(__builtin_altivec_vgbbd, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vbpermq, "V2ULLiV16UcV16Uc", "")
// P8 Crypto built-ins.
BUILTIN(__builtin_altivec_crypto_vsbox, "V2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_crypto_vpermxor, "V16UcV16UcV16UcV16Uc", "")

Просмотреть файл

@ -24,4 +24,229 @@ BUILTIN(__builtin_tx_nesting_depth, "i", "nc")
BUILTIN(__builtin_tx_assist, "vi", "n")
BUILTIN(__builtin_non_tx_store, "vULi*ULi", "")
// Vector intrinsics.
// These all map directly to z instructions, except that some variants ending
// in "s" have a final "int *" that receives the post-instruction CC value.
// Vector support instructions (chapter 21 of the PoP)
BUILTIN(__builtin_s390_lcbb, "UivC*Ii", "nc")
BUILTIN(__builtin_s390_vlbb, "V16ScvC*Ii", "")
BUILTIN(__builtin_s390_vll, "V16ScUivC*", "")
BUILTIN(__builtin_s390_vstl, "vV16ScUiv*", "")
BUILTIN(__builtin_s390_vperm, "V16UcV16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vpdi, "V2ULLiV2ULLiV2ULLiIi", "nc")
BUILTIN(__builtin_s390_vpksh, "V16ScV8SsV8Ss", "nc")
BUILTIN(__builtin_s390_vpkshs, "V16ScV8SsV8Ssi*", "nc")
BUILTIN(__builtin_s390_vpksf, "V8SsV4SiV4Si", "nc")
BUILTIN(__builtin_s390_vpksfs, "V8SsV4SiV4Sii*", "nc")
BUILTIN(__builtin_s390_vpksg, "V4SiV2SLLiV2SLLi", "nc")
BUILTIN(__builtin_s390_vpksgs, "V4SiV2SLLiV2SLLii*", "nc")
BUILTIN(__builtin_s390_vpklsh, "V16UcV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vpklshs, "V16UcV8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vpklsf, "V8UsV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vpklsfs, "V8UsV4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vpklsg, "V4UiV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vpklsgs, "V4UiV2ULLiV2ULLii*", "nc")
BUILTIN(__builtin_s390_vuphb, "V8SsV16Sc", "nc")
BUILTIN(__builtin_s390_vuphh, "V4SiV8Ss", "nc")
BUILTIN(__builtin_s390_vuphf, "V2SLLiV4Si", "nc")
BUILTIN(__builtin_s390_vuplb, "V8SsV16Sc", "nc")
BUILTIN(__builtin_s390_vuplhw, "V4SiV8Ss", "nc")
BUILTIN(__builtin_s390_vuplf, "V2SLLiV4Si", "nc")
BUILTIN(__builtin_s390_vuplhb, "V8UsV16Uc", "nc")
BUILTIN(__builtin_s390_vuplhh, "V4UiV8Us", "nc")
BUILTIN(__builtin_s390_vuplhf, "V2ULLiV4Ui", "nc")
BUILTIN(__builtin_s390_vupllb, "V8UsV16Uc", "nc")
BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc")
BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc")
// Vector integer instructions (chapter 22 of the PoP)
BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc")
BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc")
BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc")
BUILTIN(__builtin_s390_vavgg, "V2SLLiV2SLLiV2SLLi", "nc")
BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc")
BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc")
BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc")
BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc")
BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc")
BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc")
BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc")
BUILTIN(__builtin_s390_vchgs, "V2SLLiV2SLLiV2SLLii*", "nc")
BUILTIN(__builtin_s390_vchlbs, "V16ScV16UcV16Uci*", "nc")
BUILTIN(__builtin_s390_vchlhs, "V8SsV8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vchlfs, "V4SiV4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vchlgs, "V2SLLiV2ULLiV2ULLii*", "nc")
BUILTIN(__builtin_s390_vcksm, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vclzb, "V16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vclzh, "V8UsV8Us", "nc")
BUILTIN(__builtin_s390_vclzf, "V4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vclzg, "V2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vctzb, "V16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vctzh, "V8UsV8Us", "nc")
BUILTIN(__builtin_s390_vctzf, "V4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vctzg, "V2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc")
BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc")
BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc")
BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc")
BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc")
BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc")
BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc")
BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc")
BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc")
BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc")
BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc")
BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc")
BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc")
BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc")
BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc")
BUILTIN(__builtin_s390_vmalhb, "V16UcV16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vmalhh, "V8UsV8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vmalhf, "V4UiV4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vmaeb, "V8SsV16ScV16ScV8Ss", "nc")
BUILTIN(__builtin_s390_vmaeh, "V4SiV8SsV8SsV4Si", "nc")
BUILTIN(__builtin_s390_vmaef, "V2SLLiV4SiV4SiV2SLLi", "nc")
BUILTIN(__builtin_s390_vmaleb, "V8UsV16UcV16UcV8Us", "nc")
BUILTIN(__builtin_s390_vmaleh, "V4UiV8UsV8UsV4Ui", "nc")
BUILTIN(__builtin_s390_vmalef, "V2ULLiV4UiV4UiV2ULLi", "nc")
BUILTIN(__builtin_s390_vmaob, "V8SsV16ScV16ScV8Ss", "nc")
BUILTIN(__builtin_s390_vmaoh, "V4SiV8SsV8SsV4Si", "nc")
BUILTIN(__builtin_s390_vmaof, "V2SLLiV4SiV4SiV2SLLi", "nc")
BUILTIN(__builtin_s390_vmalob, "V8UsV16UcV16UcV8Us", "nc")
BUILTIN(__builtin_s390_vmaloh, "V4UiV8UsV8UsV4Ui", "nc")
BUILTIN(__builtin_s390_vmalof, "V2ULLiV4UiV4UiV2ULLi", "nc")
BUILTIN(__builtin_s390_vmhb, "V16ScV16ScV16Sc", "nc")
BUILTIN(__builtin_s390_vmhh, "V8SsV8SsV8Ss", "nc")
BUILTIN(__builtin_s390_vmhf, "V4SiV4SiV4Si", "nc")
BUILTIN(__builtin_s390_vmlhb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vmlhh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vmlhf, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vmeb, "V8SsV16ScV16Sc", "nc")
BUILTIN(__builtin_s390_vmeh, "V4SiV8SsV8Ss", "nc")
BUILTIN(__builtin_s390_vmef, "V2SLLiV4SiV4Si", "nc")
BUILTIN(__builtin_s390_vmleb, "V8UsV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vmleh, "V4UiV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vmlef, "V2ULLiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vmob, "V8SsV16ScV16Sc", "nc")
BUILTIN(__builtin_s390_vmoh, "V4SiV8SsV8Ss", "nc")
BUILTIN(__builtin_s390_vmof, "V2SLLiV4SiV4Si", "nc")
BUILTIN(__builtin_s390_vmlob, "V8UsV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vmloh, "V4UiV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vmlof, "V2ULLiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc")
BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc")
BUILTIN(__builtin_s390_vsra, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsrab, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsrl, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsrlb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc")
BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc")
// Vector string instructions (chapter 23 of the PoP)
BUILTIN(__builtin_s390_vfaeb, "V16UcV16UcV16UcIi", "nc")
BUILTIN(__builtin_s390_vfaebs, "V16UcV16UcV16UcIii*", "nc")
BUILTIN(__builtin_s390_vfaeh, "V8UsV8UsV8UsIi", "nc")
BUILTIN(__builtin_s390_vfaehs, "V8UsV8UsV8UsIii*", "nc")
BUILTIN(__builtin_s390_vfaef, "V4UiV4UiV4UiIi", "nc")
BUILTIN(__builtin_s390_vfaefs, "V4UiV4UiV4UiIii*", "nc")
BUILTIN(__builtin_s390_vfaezb, "V16UcV16UcV16UcIi", "nc")
BUILTIN(__builtin_s390_vfaezbs, "V16UcV16UcV16UcIii*", "nc")
BUILTIN(__builtin_s390_vfaezh, "V8UsV8UsV8UsIi", "nc")
BUILTIN(__builtin_s390_vfaezhs, "V8UsV8UsV8UsIii*", "nc")
BUILTIN(__builtin_s390_vfaezf, "V4UiV4UiV4UiIi", "nc")
BUILTIN(__builtin_s390_vfaezfs, "V4UiV4UiV4UiIii*", "nc")
BUILTIN(__builtin_s390_vfeeb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vfeebs, "V16UcV16UcV16Uci*", "nc")
BUILTIN(__builtin_s390_vfeeh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vfeehs, "V8UsV8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vfeef, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vfeefs, "V4UiV4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vfeezb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vfeezbs, "V16UcV16UcV16Uci*", "nc")
BUILTIN(__builtin_s390_vfeezh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vfeezhs, "V8UsV8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vfeezf, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vfeezfs, "V4UiV4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vfeneb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vfenebs, "V16UcV16UcV16Uci*", "nc")
BUILTIN(__builtin_s390_vfeneh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vfenehs, "V8UsV8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vfenef, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vfenefs, "V4UiV4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vfenezb, "V16UcV16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vfenezbs, "V16UcV16UcV16Uci*", "nc")
BUILTIN(__builtin_s390_vfenezh, "V8UsV8UsV8Us", "nc")
BUILTIN(__builtin_s390_vfenezhs, "V8UsV8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vfenezf, "V4UiV4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vfenezfs, "V4UiV4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vistrb, "V16UcV16Uc", "nc")
BUILTIN(__builtin_s390_vistrbs, "V16UcV16Uci*", "nc")
BUILTIN(__builtin_s390_vistrh, "V8UsV8Us", "nc")
BUILTIN(__builtin_s390_vistrhs, "V8UsV8Usi*", "nc")
BUILTIN(__builtin_s390_vistrf, "V4UiV4Ui", "nc")
BUILTIN(__builtin_s390_vistrfs, "V4UiV4Uii*", "nc")
BUILTIN(__builtin_s390_vstrcb, "V16UcV16UcV16UcV16UcIi", "nc")
BUILTIN(__builtin_s390_vstrcbs, "V16UcV16UcV16UcV16UcIii*", "nc")
BUILTIN(__builtin_s390_vstrch, "V8UsV8UsV8UsV8UsIi", "nc")
BUILTIN(__builtin_s390_vstrchs, "V8UsV8UsV8UsV8UsIii*", "nc")
BUILTIN(__builtin_s390_vstrcf, "V4UiV4UiV4UiV4UiIi", "nc")
BUILTIN(__builtin_s390_vstrcfs, "V4UiV4UiV4UiV4UiIii*", "nc")
BUILTIN(__builtin_s390_vstrczb, "V16UcV16UcV16UcV16UcIi", "nc")
BUILTIN(__builtin_s390_vstrczbs, "V16UcV16UcV16UcV16UcIii*", "nc")
BUILTIN(__builtin_s390_vstrczh, "V8UsV8UsV8UsV8UsIi", "nc")
BUILTIN(__builtin_s390_vstrczhs, "V8UsV8UsV8UsV8UsIii*", "nc")
BUILTIN(__builtin_s390_vstrczf, "V4UiV4UiV4UiV4UiIi", "nc")
BUILTIN(__builtin_s390_vstrczfs, "V4UiV4UiV4UiV4UiIii*", "nc")
// Vector floating-point instructions (chapter 24 of the PoP)
BUILTIN(__builtin_s390_vfcedbs, "V2SLLiV2dV2di*", "nc")
BUILTIN(__builtin_s390_vfchdbs, "V2SLLiV2dV2di*", "nc")
BUILTIN(__builtin_s390_vfchedbs, "V2SLLiV2dV2di*", "nc")
BUILTIN(__builtin_s390_vfidb, "V2dV2dIiIi", "nc")
BUILTIN(__builtin_s390_vflndb, "V2dV2d", "nc")
BUILTIN(__builtin_s390_vflpdb, "V2dV2d", "nc")
BUILTIN(__builtin_s390_vfmadb, "V2dV2dV2dV2d", "nc")
BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc")
BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc")
BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc")
#undef BUILTIN

Просмотреть файл

@ -825,7 +825,9 @@ BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "")
BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "")
BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "")
BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "")
BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIcUsIi", "")
BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "")
BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "")
BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "")
BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "")
BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "")
BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "")
@ -850,7 +852,9 @@ BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "")
BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "")
BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "")
BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "")
BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIcUcIi", "")
BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "")
BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "")
BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "")
BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "")
BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "")
BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "")
@ -941,29 +945,109 @@ BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "")
BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "")
BUILTIN(__builtin_ia32_knothi, "UsUs", "")
BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIcUs", "")
BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIcUc", "")
BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIcUc", "")
BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIcUc", "")
BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIcUi", "")
BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIcUc", "")
BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIcUc", "")
BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIcUs", "")
BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIcULLi", "")
BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIcUs", "")
BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIcUc", "")
BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIcUi", "")
BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIcUs", "")
BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIcUc", "")
BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIcUc", "")
BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIcUc", "")
BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIcUi", "")
BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIcUc", "")
BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIcUc", "")
BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIcUs", "")
BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIcULLi", "")
BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIcUs", "")
BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIcUc", "")
BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIcUi", "")
BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "")
BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "")
BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "")
BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "")
BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "")
BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "")
BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "")
BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "")
BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "")
BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "")
BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "")
BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "")
BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "")
BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "")
BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "")
BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "")
BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "")
BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "")
BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "")
BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "")
BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "")
BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "")
BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "")
BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "")
BUILTIN(__builtin_ia32_paddd256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "")
BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "")
BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "")
BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "")
BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_pandd256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_pandd128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_pandnd256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_pandnd128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_pord256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_pord128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_pxord256_mask, "V8iV8iV8iV8iUc", "")
BUILTIN(__builtin_ia32_pxord128_mask, "V4iV4iV4iV4iUc", "")
BUILTIN(__builtin_ia32_pandq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_pandq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_pandnq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_pandnq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_porq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_porq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_pxorq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_pxorq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "")
BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "")
BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "")
BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "")
BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "")
BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "")
BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "")
BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "")
BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "")
BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "")
BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "")
BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "")
BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "")
BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "")
BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "")
BUILTIN(__builtin_ia32_pandnd512_mask, "V16iV16iV16iV16iUs", "")
BUILTIN(__builtin_ia32_pandnq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "")
BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "")
BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "")
BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "")
BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "")
BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "")
BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "")
BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "")
BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "")
BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "")
BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "")
BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "")
BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "")
BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "")
BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "")
BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "")
BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "")
BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "")
BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "")
BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "")
BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "")
BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "")
BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "")
BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "")
BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "")
BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "")
BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "")
BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "")
BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "")
#undef BUILTIN

Просмотреть файл

@ -168,6 +168,14 @@ let CategoryName = "Inline Assembly Issue" in {
"invalid operand number in inline asm string">;
}
// vtable related.
let CategoryName = "VTable ABI Issue" in {
def err_vftable_ambiguous_component : Error<
"ambiguous vftable component for %0 introduced via covariant thunks; "
"this is an inherent limitation of the ABI">;
def note_covariant_thunk : Note<
"covariant thunk required by %0">;
}
// Importing ASTs
def err_odr_variable_type_inconsistent : Error<

Просмотреть файл

@ -115,7 +115,23 @@ def err_integer_literal_too_large : Error<
def ext_integer_literal_too_large_for_signed : ExtWarn<
"integer literal is too large to be represented in a signed integer type, "
"interpreting as unsigned">,
InGroup<DiagGroup<"implicitly-unsigned-literal">>;
InGroup<ImplicitlyUnsignedLiteral>;
def warn_old_implicitly_unsigned_long : Warning<
"integer literal is too large to be represented in type 'long', "
"interpreting as 'unsigned long' per C89; this literal will "
"%select{have type 'long long'|be ill-formed}0 in C99 onwards">,
InGroup<C99Compat>;
def warn_old_implicitly_unsigned_long_cxx : Warning<
"integer literal is too large to be represented in type 'long', "
"interpreting as 'unsigned long' per C++98; this literal will "
"%select{have type 'long long'|be ill-formed}0 in C++11 onwards">,
InGroup<CXX11Compat>;
def ext_old_implicitly_unsigned_long_cxx : ExtWarn<
"integer literal is too large to be represented in type 'long' and is "
"subject to undefined behavior under C++98, interpreting as 'unsigned long'; "
"this literal will %select{have type 'long long'|be ill-formed}0 "
"in C++11 onwards">,
InGroup<CXX11Compat>;
// SEH
def err_seh_expected_handler : Error<

Просмотреть файл

@ -239,6 +239,7 @@ def MultiChar : DiagGroup<"multichar">;
def : DiagGroup<"nested-externs">;
def CXX11LongLong : DiagGroup<"c++11-long-long">;
def LongLong : DiagGroup<"long-long", [CXX11LongLong]>;
def ImplicitlyUnsignedLiteral : DiagGroup<"implicitly-unsigned-literal">;
def MethodSignatures : DiagGroup<"method-signatures">;
def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
@ -264,6 +265,8 @@ def : DiagGroup<"overflow">;
def ForwardClassReceiver : DiagGroup<"receiver-forward-class">;
def MethodAccess : DiagGroup<"objc-method-access">;
def ObjCReceiver : DiagGroup<"receiver-expr">;
// FIXME: Remove this when Xcode removes the warning setting.
def : DiagGroup<"receiver-is-weak">;
def OperatorNewReturnsNull : DiagGroup<"new-returns-null">;
def OverlengthStrings : DiagGroup<"overlength-strings">;
def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
@ -286,6 +289,7 @@ def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
def PessimizingMove : DiagGroup<"pessimizing-move">;
def PointerArith : DiagGroup<"pointer-arith">;
def PoundWarning : DiagGroup<"#warnings">;
def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
@ -294,6 +298,7 @@ def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def RedeclaredClassMember : DiagGroup<"redeclared-class-member">;
def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">;
def RedundantMove : DiagGroup<"redundant-move">;
def ReturnStackAddress : DiagGroup<"return-stack-address">;
def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">;
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
@ -399,6 +404,7 @@ def UnknownAttributes : DiagGroup<"unknown-attributes">;
def IgnoredAttributes : DiagGroup<"ignored-attributes">;
def Attributes : DiagGroup<"attributes", [UnknownAttributes,
IgnoredAttributes]>;
def UnknownSanitizers : DiagGroup<"unknown-sanitizers">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
[CXX98CompatUnnamedTypeTemplateArgs]>;
def UnsupportedFriend : DiagGroup<"unsupported-friend">;
@ -574,6 +580,8 @@ def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
[IntToVoidPointerCast]>;
def Move : DiagGroup<"move", [PessimizingMove, RedundantMove, SelfMove]>;
def Extra : DiagGroup<"extra", [
MissingFieldInitializers,
IgnoredQualifiers,
@ -592,6 +600,7 @@ def Most : DiagGroup<"most", [
Implicit,
MismatchedTags,
MissingBraces,
Move,
MultiChar,
Reorder,
ReturnType,

Просмотреть файл

@ -34,7 +34,7 @@ namespace clang {
DIAG_START_LEX = DIAG_START_SERIALIZATION + 120,
DIAG_START_PARSE = DIAG_START_LEX + 300,
DIAG_START_AST = DIAG_START_PARSE + 500,
DIAG_START_COMMENT = DIAG_START_AST + 100,
DIAG_START_COMMENT = DIAG_START_AST + 110,
DIAG_START_SEMA = DIAG_START_COMMENT + 100,
DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000,
DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100

Просмотреть файл

@ -638,7 +638,9 @@ def warn_non_modular_include_in_framework_module : Warning<
def warn_non_modular_include_in_module : Warning<
"include of non-modular header inside module '%0'">,
InGroup<NonModularIncludeInModule>, DefaultIgnore;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
InGroup<ModuleConflict>;
def warn_header_guard : Warning<
"%0 is used as a header guard here, followed by #define of a different macro">,

Просмотреть файл

@ -69,7 +69,10 @@ ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1,
DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected
/// diagnostics, indicated by markers in the
/// input source file.
ENUM_DIAGOPT(VerifyIgnoreUnexpected, DiagnosticLevelMask, 4,
DiagnosticLevelMask::None) /// Ignore unexpected diagnostics of
/// the specified levels when using
/// -verify.
DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing
DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing
DIAGOPT(CLFallbackMode, 1, 0) /// Format for clang-cl fallback mode

Просмотреть файл

@ -13,6 +13,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include <string>
#include <type_traits>
#include <vector>
namespace clang {
@ -24,6 +25,38 @@ enum OverloadsShown : unsigned {
Ovl_Best ///< Show just the "best" overload candidates.
};
/// \brief A bitmask representing the diagnostic levels used by
/// VerifyDiagnosticConsumer.
enum class DiagnosticLevelMask : unsigned {
None = 0,
Note = 1 << 0,
Remark = 1 << 1,
Warning = 1 << 2,
Error = 1 << 3,
All = Note | Remark | Warning | Error
};
inline DiagnosticLevelMask operator~(DiagnosticLevelMask M) {
using UT = std::underlying_type<DiagnosticLevelMask>::type;
return static_cast<DiagnosticLevelMask>(~static_cast<UT>(M));
}
inline DiagnosticLevelMask operator|(DiagnosticLevelMask LHS,
DiagnosticLevelMask RHS) {
using UT = std::underlying_type<DiagnosticLevelMask>::type;
return static_cast<DiagnosticLevelMask>(
static_cast<UT>(LHS) | static_cast<UT>(RHS));
}
inline DiagnosticLevelMask operator&(DiagnosticLevelMask LHS,
DiagnosticLevelMask RHS) {
using UT = std::underlying_type<DiagnosticLevelMask>::type;
return static_cast<DiagnosticLevelMask>(
static_cast<UT>(LHS) & static_cast<UT>(RHS));
}
raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M);
/// \brief Options for controlling the compiler diagnostics engine.
class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
public:

Просмотреть файл

@ -170,6 +170,7 @@ def err_function_declared_typedef : Error<
"function definition declared 'typedef'">;
def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">;
def err_at_in_class : Error<"unexpected '@' in member specification">;
def err_unexpected_semi : Error<"unexpected ';' before %0">;
def err_expected_fn_body : Error<
"expected function body after function declarator">;
@ -477,7 +478,8 @@ def err_invalid_operator_on_type : Error<
def err_expected_unqualified_id : Error<
"expected %select{identifier|unqualified-id}0">;
def err_brackets_go_after_unqualified_id : Error<
"brackets go after the %select{identifier|unqualified-id}0">;
"brackets are not allowed here; to declare an array, "
"place the brackets after the %select{identifier|name}0">;
def err_unexpected_unqualified_id : Error<"type-id cannot have a name">;
def err_func_def_no_params : Error<
"function definition does not declare parameters">;
@ -987,12 +989,12 @@ def err_omp_expected_identifier_for_critical : Error<
// Pragma loop support.
def err_pragma_loop_missing_argument : Error<
"missing argument; expected %select{an integer value|"
"'%select{enable|full}1' or 'disable'}0">;
"%select{'enable', 'assume_safety'|'full'}1 or 'disable'}0">;
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
"vectorize_width, interleave, interleave_count, unroll, or unroll_count">;
def err_pragma_invalid_keyword : Error<
"invalid argument; expected '%select{enable|full}0' or 'disable'">;
"invalid argument; expected %select{'enable', 'assume_safety'|'full'}0 or 'disable'">;
// Pragma unroll support.
def warn_pragma_unroll_cuda_value_in_parens : Warning<

Просмотреть файл

@ -108,6 +108,7 @@ def err_ice_ambiguous_conversion : Error<
def err_ice_too_large : Error<
"integer constant expression evaluates to value %0 that cannot be "
"represented in a %1-bit %select{signed|unsigned}2 integer type">;
def err_expr_not_string_literal : Error<"expression is not a string literal">;
// Semantic analysis of constant literals.
def ext_predef_outside_function : Warning<
@ -424,6 +425,7 @@ def warn_redecl_library_builtin : Warning<
"incompatible redeclaration of library function %0">,
InGroup<DiagGroup<"incompatible-library-redeclaration">>;
def err_builtin_definition : Error<"definition of builtin function %0">;
def err_arm_invalid_specialreg : Error<"invalid special register for builtin">;
def warn_builtin_unknown : Warning<"use of unknown builtin %0">,
InGroup<ImplicitFunctionDeclare>, DefaultError;
def warn_dyn_class_memaccess : Warning<
@ -485,6 +487,8 @@ def warn_static_main : Warning<"'main' should not be declared static">,
InGroup<Main>;
def err_static_main : Error<"'main' is not allowed to be declared static">;
def err_inline_main : Error<"'main' is not allowed to be declared inline">;
def ext_variadic_main : ExtWarn<
"'main' is not allowed to be declared variadic">, InGroup<Main>;
def ext_noreturn_main : ExtWarn<
"'main' is not allowed to be declared _Noreturn">, InGroup<Main>;
def note_main_remove_noreturn : Note<"remove '_Noreturn'">;
@ -906,10 +910,6 @@ def warn_dealloc_in_category : Warning<
InGroup<DeallocInCategory>;
def err_gc_weak_property_strong_type : Error<
"weak attribute declared on a __strong type property in GC mode">;
def warn_receiver_is_weak : Warning <
"weak %select{receiver|property|implicit property}0 may be "
"unpredictably set to nil">,
InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore;
def warn_arc_repeated_use_of_weak : Warning <
"weak %select{variable|property|implicit property|instance variable}0 %1 is "
"accessed multiple times in this %select{function|method|block|lambda}2 "
@ -1488,8 +1488,10 @@ def err_lvalue_reference_bind_to_unrelated : Error<
"%diff{to type $ cannot bind to a value of unrelated type $|"
"cannot bind to a value of unrelated type}1,2">;
def err_reference_bind_drops_quals : Error<
"binding of reference %diff{to type $ to a value of type $ drops qualifiers|"
"drops qualifiers}0,1">;
"binding value %diff{of type $ to reference to type $|to reference}0,1 "
"drops %select{<<ERROR>>|'const'|'restrict'|'const' and 'restrict'|"
"'volatile'|'const' and 'volatile'|'restrict' and 'volatile'|"
"'const', 'restrict', and 'volatile'}2 qualifier%plural{1:|2:|4:|:s}2">;
def err_reference_bind_failed : Error<
"reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of "
"type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2">;
@ -1974,8 +1976,11 @@ def err_attribute_too_few_arguments : Error<
def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
def err_attribute_bad_neon_vector_size : Error<
"Neon vector size must be 64 or 128 bits">;
def err_attribute_unsupported : Error<
"%0 attribute is not supported for this target">;
def warn_unsupported_target_attribute
: Warning<"Ignoring unsupported '%0' in the target attribute string">,
InGroup<IgnoredAttributes>;
def err_attribute_unsupported
: Error<"%0 attribute is not supported for this target">;
// The err_*_attribute_argument_not_int are seperate because they're used by
// VerifyIntegerConstantExpression.
def err_aligned_attribute_argument_not_int : Error<
@ -2120,6 +2125,9 @@ def note_objc_literal_comparison_isequal : Note<
"use 'isEqual:' instead">;
def err_attribute_argument_is_zero : Error<
"%0 attribute must be greater than 0">;
def warn_attribute_argument_n_negative : Warning<
"%0 attribute parameter %1 is negative and will be ignored">,
InGroup<CudaCompat>;
def err_property_function_in_objc_container : Error<
"use of Objective-C property in function nested in Objective-C "
"container not supported, move function outside its container">;
@ -2246,7 +2254,7 @@ def warn_attribute_dllimport_static_field_definition : Warning<
InGroup<DiagGroup<"dllimport-static-field-def">>;
def warn_attribute_dllexport_explicit_instantiation_decl : Warning<
"explicit instantiation declaration should not be 'dllexport'">,
InGroup<DiagGroup<"dllexport-explicit-instantation-decl">>;
InGroup<DiagGroup<"dllexport-explicit-instantiation-decl">>;
def warn_invalid_initializer_from_system_header : Warning<
"invalid constructor form class in system header, should not be explicit">,
InGroup<DiagGroup<"invalid-initializer-from-system-header">>;
@ -2255,8 +2263,7 @@ def err_attribute_dll_member_of_dll_class : Error<
"attribute %q0 cannot be applied to member of %q1 class">;
def warn_attribute_dll_instantiated_base_class : Warning<
"propagating dll attribute to %select{already instantiated|explicitly specialized}0 "
"base class template "
"%select{without dll attribute|with different dll attribute}1 is not supported">,
"base class template without dll attribute is not supported">,
InGroup<DiagGroup<"unsupported-dll-base-class-template">>, DefaultIgnore;
def err_attribute_weakref_not_static : Error<
"weakref declaration must have internal linkage">;
@ -2514,6 +2521,10 @@ def warn_param_typestate_mismatch : Warning<
"argument not in expected state; expected '%0', observed '%1'">,
InGroup<Consumed>, DefaultIgnore;
// no_sanitize attribute
def warn_unknown_sanitizer_ignored : Warning<
"unknown sanitizer '%0' ignored">, InGroup<UnknownSanitizers>;
def warn_impcast_vector_scalar : Warning<
"implicit conversion turns vector to scalar: %0 to %1">,
InGroup<Conversion>, DefaultIgnore;
@ -4150,8 +4161,11 @@ def err_typecheck_negative_array_size : Error<"array size is negative">;
def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
// FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
InGroup<BadArrayNewLength>;
def warn_typecheck_function_qualifiers : Warning<
"qualifier on function type %0 has unspecified behavior">;
def warn_typecheck_function_qualifiers_ignored : Warning<
"'%0' qualifier on function type %1 has no effect">,
InGroup<IgnoredQualifiers>;
def warn_typecheck_function_qualifiers_unspecified : Warning<
"'%0' qualifier on function type %1 has unspecified behavior">;
def warn_typecheck_reference_qualifiers : Warning<
"'%0' qualifier on reference type %1 has no effect">,
InGroup<IgnoredQualifiers>;
@ -4772,6 +4786,17 @@ def warn_self_move : Warning<
"explicitly moving variable of type %0 to itself">,
InGroup<SelfMove>, DefaultIgnore;
def warn_redundant_move_on_return : Warning<
"redundant move in return statement">,
InGroup<RedundantMove>, DefaultIgnore;
def warn_pessimizing_move_on_return : Warning<
"moving a local object in a return statement prevents copy elision">,
InGroup<PessimizingMove>, DefaultIgnore;
def warn_pessimizing_move_on_initialization : Warning<
"moving a temporary object prevents copy elision">,
InGroup<PessimizingMove>, DefaultIgnore;
def note_remove_move : Note<"remove std::move call here">;
def warn_string_plus_int : Warning<
"adding %0 to a string does not append to the string">,
InGroup<StringPlusInt>;
@ -5005,7 +5030,7 @@ def err_typecheck_unary_expr : Error<
"invalid argument type %0 to unary expression">;
def err_typecheck_indirection_requires_pointer : Error<
"indirection requires pointer operand (%0 invalid)">;
def ext_typecheck_indirection_through_void_pointer : Extension<
def ext_typecheck_indirection_through_void_pointer : ExtWarn<
"ISO C++ does not allow indirection on operand of type %0">,
InGroup<DiagGroup<"void-ptr-dereference">>;
def warn_indirection_through_null : Warning<
@ -5365,6 +5390,10 @@ def err_bad_const_cast_dest : Error<
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
def ext_cast_fn_obj : Extension<
"cast between pointer-to-function and pointer-to-object is an extension">;
def ext_ms_cast_fn_obj : ExtWarn<
"static_cast between pointer-to-function and pointer-to-object is a "
"Microsoft extension">,
InGroup<Microsoft>;
def warn_cxx98_compat_cast_fn_obj : Warning<
"cast between pointer-to-function and pointer-to-object is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
@ -5470,8 +5499,11 @@ def err_address_space_qualified_delete : Error<
def err_default_init_const : Error<
"default initialization of an object of const type %0"
"%select{| without a user-provided default constructor}1">;
def note_add_initializer : Note<
"add an explicit initializer to initialize %0">;
def ext_default_init_const : ExtWarn<
"default initialization of an object of const type %0"
"%select{| without a user-provided default constructor}1 "
"is a Microsoft extension">,
InGroup<Microsoft>;
def err_delete_operand : Error<"cannot delete expression of type %0">;
def ext_delete_void_ptr_operand : ExtWarn<
"cannot delete expression with pointer-to-'void' type %0">,
@ -5488,7 +5520,12 @@ def err_delete_explicit_conversion : Error<
"conversion function">;
def note_delete_conversion : Note<"conversion to pointer type %0">;
def warn_delete_array_type : Warning<
"'delete' applied to a pointer-to-array type %0 treated as delete[]">;
"'delete' applied to a pointer-to-array type %0 treated as 'delete[]'">;
def warn_mismatched_delete_new : Warning<
"'delete%select{|[]}0' applied to a pointer that was allocated with "
"'new%select{[]|}0'; did you mean 'delete%select{[]|}0'?">,
InGroup<DiagGroup<"mismatched-new-delete">>;
def note_allocated_here : Note<"allocated with 'new%select{[]|}0' here">;
def err_no_suitable_delete_member_function_found : Error<
"no suitable member %0 in %1">;
def err_ambiguous_suitable_delete_member_function_found : Error<
@ -6301,6 +6338,9 @@ let CategoryName = "Inline Assembly Issue" in {
"remove the cast or build with -fheinous-gnu-extensions">;
def err_invalid_asm_value_for_constraint
: Error <"value '%0' out of range for constraint '%1'">;
def err_asm_bitfield_in_memory_constraint
: Error <"reference to a bit-field in asm "
"%select{input|output}0 with a memory constraint '%1'">;
def warn_asm_label_on_auto_decl : Warning<
"ignored asm label '%0' on automatic variable">;
@ -7371,8 +7411,6 @@ def err_omp_unexpected_clause_value : Error<
"expected %0 in OpenMP clause '%1'">;
def err_omp_expected_var_name : Error<
"expected variable name">;
def err_omp_required_method : Error<
"%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">;
def note_omp_task_predetermined_firstprivate_here : Note<
"predetermined as a firstprivate in a task construct here">;
def err_omp_clause_ref_type_arg : Error<
@ -7385,6 +7423,8 @@ def err_omp_no_dsa_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes">;
def err_omp_wrong_dsa : Error<
"%0 variable cannot be %1">;
def err_omp_variably_modified_type_not_supported : Error<
"arguments of OpenMP clause '%0' in '#pragma omp %2' directive cannot be of variably-modified type %1">;
def note_omp_explicit_dsa : Note<
"defined as %0">;
def note_omp_predetermined_dsa : Note<
@ -7402,8 +7442,6 @@ def note_omp_implicit_dsa : Note<
"implicitly determined as %0">;
def err_omp_loop_var_dsa : Error<
"loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
def err_omp_global_loop_var_dsa : Error<
"loop iteration variable in the associated loop of 'omp %1' directive may not be a variable with global storage without being explicitly marked as %0">;
def err_omp_not_for : Error<
"%select{statement after '#pragma omp %1' must be a for loop|"
"expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
@ -7599,9 +7637,11 @@ def err_module_private_local_class : Error<
"local %select{struct|interface|union|class|enum}0 cannot be declared "
"__module_private__">;
def err_module_private_declaration : Error<
"declaration of %0 must be imported from module '%1' before it is required">;
def err_module_private_definition : Error<
"definition of %0 must be imported from module '%1' before it is required">;
"%select{declaration|definition}0 of %1 must be imported from "
"module '%2' before it is required">;
def err_module_private_declaration_multiple : Error<
"%select{declaration|definition}0 of %1 must be imported from "
"one of the following modules before it is required:%2">;
def err_module_import_in_extern_c : Error<
"import of C++ module '%0' appears within extern \"C\" language linkage "
"specification">;

Просмотреть файл

@ -66,9 +66,6 @@ def err_imported_module_relocated : Error<
def err_module_different_modmap : Error<
"module '%0' %select{uses|does not use}1 additional module map '%2'"
"%select{| not}1 used when the module was built">;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
InGroup<ModuleConflict>;
def err_pch_macro_def_undef : Error<
"macro '%0' was %select{defined|undef'd}1 in the precompiled header but "

Просмотреть файл

@ -25,16 +25,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include <memory>
// FIXME: Enhance libsystem to support inode and other fields in stat.
#include <sys/types.h>
#include <map>
#ifdef _MSC_VER
typedef unsigned short mode_t;
#endif
struct stat;
namespace llvm {
class MemoryBuffer;
}

Просмотреть файл

@ -53,7 +53,8 @@ class IdentifierInfo {
bool HasMacro : 1; // True if there is a #define for this.
bool HadMacro : 1; // True if there was a #define for this.
bool IsExtension : 1; // True if identifier is a lang extension.
bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11.
bool IsFutureCompatKeyword : 1; // True if identifier is a keyword in a
// newer Standard or proposed Standard.
bool IsPoisoned : 1; // True if identifier is poisoned.
bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier".
@ -124,6 +125,7 @@ public:
}
/// \brief Return true if this identifier is \#defined to some other value.
/// \note The current definition may be in a module and not currently visible.
bool hasMacroDefinition() const {
return HasMacro;
}
@ -212,13 +214,14 @@ public:
RecomputeNeedsHandleIdentifier();
}
/// is/setIsCXX11CompatKeyword - Initialize information about whether or not
/// this language token is a keyword in C++11. This controls compatibility
/// warnings, and is only true when not parsing C++11. Once a compatibility
/// problem has been diagnosed with this keyword, the flag will be cleared.
bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; }
void setIsCXX11CompatKeyword(bool Val) {
IsCXX11CompatKeyword = Val;
/// is/setIsFutureCompatKeyword - Initialize information about whether or not
/// this language token is a keyword in a newer or proposed Standard. This
/// controls compatibility warnings, and is only true when not parsing the
/// corresponding Standard. Once a compatibility problem has been diagnosed
/// with this keyword, the flag will be cleared.
bool isFutureCompatKeyword() const { return IsFutureCompatKeyword; }
void setIsFutureCompatKeyword(bool Val) {
IsFutureCompatKeyword = Val;
if (Val)
NeedsHandleIdentifier = 1;
else
@ -324,7 +327,7 @@ private:
void RecomputeNeedsHandleIdentifier() {
NeedsHandleIdentifier =
(isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
isExtensionToken() | isCXX11CompatKeyword() || isOutOfDate() ||
isExtensionToken() | isFutureCompatKeyword() || isOutOfDate() ||
isModulesImport());
}
};

Просмотреть файл

@ -130,6 +130,7 @@ COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module us
LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
BENIGN_LANGOPT(ModulesImplicitMaps, 1, 1, "use files called module.modulemap implicitly as module maps")
BENIGN_LANGOPT(ImplicitModules, 1, 1, "build modules that are not specified via -fmodule-file")
COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility")
COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
@ -166,6 +167,7 @@ LANGOPT(CUDADisableTargetCallChecks, 1, 0, "Disable checks for call targets (hos
LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions")
LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")

Просмотреть файл

@ -67,6 +67,13 @@ public:
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
enum MSVCMajorVersion {
MSVC2010 = 16,
MSVC2012 = 17,
MSVC2013 = 18,
MSVC2015 = 19
};
public:
/// \brief Set of enabled sanitizers.
SanitizerSet Sanitize;
@ -118,7 +125,7 @@ public:
!ObjCSubscriptingLegacyRuntime;
}
bool isCompatibleWithMSVC(unsigned MajorVersion) const {
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
return MSCompatibilityVersion >= MajorVersion * 10000000U;
}

Просмотреть файл

@ -14,6 +14,10 @@
#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H
#include <assert.h>
#include <stdint.h>
#include <utility>
namespace clang {
/// \brief Describes the different kinds of linkage

Просмотреть файл

@ -16,11 +16,13 @@
#define LLVM_CLANG_BASIC_MODULE_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@ -63,6 +65,9 @@ public:
/// \brief The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
/// \brief The name of the umbrella entry, as written in the module map.
std::string UmbrellaAsWritten;
private:
/// \brief The submodules of this module, indexed by name.
@ -85,6 +90,9 @@ private:
/// \brief Cache of modules visible to lookup in this module.
mutable llvm::DenseSet<const Module*> VisibleModulesCache;
/// The ID used when referencing this module within a VisibleModuleSet.
unsigned VisibilityID;
public:
enum HeaderKind {
HK_Normal,
@ -100,6 +108,17 @@ public:
struct Header {
std::string NameAsWritten;
const FileEntry *Entry;
explicit operator bool() { return Entry; }
};
/// \brief Information about a directory name as found in the module map
/// file.
struct DirectoryName {
std::string NameAsWritten;
const DirectoryEntry *Entry;
explicit operator bool() { return Entry; }
};
/// \brief The headers that are part of this module.
@ -182,10 +201,7 @@ public:
/// particular module.
enum NameVisibilityKind {
/// \brief All of the names in this module are hidden.
///
Hidden,
/// \brief Only the macro names in this module are visible.
MacrosVisible,
/// \brief All of the names in this module are visible.
AllVisible
};
@ -193,15 +209,12 @@ public:
/// \brief The visibility of names within this particular module.
NameVisibilityKind NameVisibility;
/// \brief The location at which macros within this module became visible.
SourceLocation MacroVisibilityLoc;
/// \brief The location of the inferred submodule.
SourceLocation InferredSubmoduleLoc;
/// \brief The set of modules imported by this module, and on which this
/// module depends.
SmallVector<Module *, 2> Imports;
llvm::SmallSetVector<Module *, 2> Imports;
/// \brief Describes an exported module.
///
@ -288,7 +301,7 @@ public:
/// \brief Construct a new module or submodule.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
bool IsFramework, bool IsExplicit);
bool IsFramework, bool IsExplicit, unsigned VisibilityID);
~Module();
@ -371,12 +384,14 @@ public:
/// \brief Retrieve the directory for which this module serves as the
/// umbrella.
const DirectoryEntry *getUmbrellaDir() const;
DirectoryName getUmbrellaDir() const;
/// \brief Retrieve the header that serves as the umbrella header for this
/// module.
const FileEntry *getUmbrellaHeader() const {
return Umbrella.dyn_cast<const FileEntry *>();
Header getUmbrellaHeader() const {
if (auto *E = Umbrella.dyn_cast<const FileEntry *>())
return Header{UmbrellaAsWritten, E};
return Header{};
}
/// \brief Determine whether this module has an umbrella directory that is
@ -441,6 +456,8 @@ public:
return VisibleModulesCache.count(M);
}
unsigned getVisibilityID() const { return VisibilityID; }
typedef std::vector<Module *>::iterator submodule_iterator;
typedef std::vector<Module *>::const_iterator submodule_const_iterator;
@ -470,6 +487,65 @@ private:
void buildVisibleModulesCache() const;
};
/// \brief A set of visible modules.
class VisibleModuleSet {
public:
VisibleModuleSet() : Generation(0) {}
VisibleModuleSet(VisibleModuleSet &&O)
: ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) {
O.ImportLocs.clear();
++O.Generation;
}
/// Move from another visible modules set. Guaranteed to leave the source
/// empty and bump the generation on both.
VisibleModuleSet &operator=(VisibleModuleSet &&O) {
ImportLocs = std::move(O.ImportLocs);
O.ImportLocs.clear();
++O.Generation;
++Generation;
return *this;
}
/// \brief Get the current visibility generation. Incremented each time the
/// set of visible modules changes in any way.
unsigned getGeneration() const { return Generation; }
/// \brief Determine whether a module is visible.
bool isVisible(const Module *M) const {
return getImportLoc(M).isValid();
}
/// \brief Get the location at which the import of a module was triggered.
SourceLocation getImportLoc(const Module *M) const {
return M->getVisibilityID() < ImportLocs.size()
? ImportLocs[M->getVisibilityID()]
: SourceLocation();
}
/// \brief A callback to call when a module is made visible (directly or
/// indirectly) by a call to \ref setVisible.
typedef llvm::function_ref<void(Module *M)> VisibleCallback;
/// \brief A callback to call when a module conflict is found. \p Path
/// consists of a sequence of modules from the conflicting module to the one
/// made visible, where each was exported by the next.
typedef llvm::function_ref<void(ArrayRef<Module *> Path,
Module *Conflict, StringRef Message)>
ConflictCallback;
/// \brief Make a specific module visible.
void setVisible(Module *M, SourceLocation Loc,
VisibleCallback Vis = [](Module *) {},
ConflictCallback Cb = [](ArrayRef<Module *>, Module *,
StringRef) {});
private:
/// Import locations for each visible module. Indexed by the module's
/// VisibilityID.
std::vector<SourceLocation> ImportLocs;
/// Visibility generation, bumped every time the visibility state changes.
unsigned Generation;
};
} // end namespace clang

Просмотреть файл

@ -87,6 +87,9 @@ SANITIZER("cfi-vcall", CFIVCall)
SANITIZER_GROUP("cfi", CFI,
CFIDerivedCast | CFIUnrelatedCast | CFINVCall | CFIVCall)
// Safe Stack
SANITIZER("safe-stack", SafeStack)
// -fsanitize=undefined-trap includes sanitizers from -fsanitize=undefined
// that can be used without runtime support, generally by providing extra
// -fsanitize-undefined-trap-on-error flag.

Просмотреть файл

@ -15,33 +15,64 @@
#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
#define LLVM_CLANG_BASIC_SANITIZERS_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include <stdint.h>
namespace clang {
enum class SanitizerKind {
#define SANITIZER(NAME, ID) ID,
typedef uint64_t SanitizerMask;
namespace SanitizerKind {
// Assign ordinals to possible values of -fsanitize= flag, which we will use as
// bit positions.
enum SanitizerOrdinal : uint64_t {
#define SANITIZER(NAME, ID) SO_##ID,
#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
#include "clang/Basic/Sanitizers.def"
Unknown
SO_Count
};
class SanitizerSet {
/// \brief Bitmask of enabled sanitizers.
unsigned Kinds;
public:
// Define the set of sanitizer kinds, as well as the set of sanitizers each
// sanitizer group expands into.
#define SANITIZER(NAME, ID) \
const SanitizerMask ID = 1ULL << SO_##ID;
#define SANITIZER_GROUP(NAME, ID, ALIAS) \
const SanitizerMask ID = ALIAS; \
const SanitizerMask ID##Group = 1ULL << SO_##ID##Group;
#include "clang/Basic/Sanitizers.def"
}
struct SanitizerSet {
SanitizerSet();
/// \brief Check if a certain sanitizer is enabled.
bool has(SanitizerKind K) const;
/// \brief Check if a certain (single) sanitizer is enabled.
bool has(SanitizerMask K) const;
/// \brief Enable or disable a certain sanitizer.
void set(SanitizerKind K, bool Value);
/// \brief Enable or disable a certain (single) sanitizer.
void set(SanitizerMask K, bool Value);
/// \brief Disable all sanitizers.
void clear();
/// \brief Returns true if at least one sanitizer is enabled.
bool empty() const;
/// \brief Bitmask of enabled sanitizers.
SanitizerMask Mask;
};
/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
/// this group enables.
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
} // end namespace clang
#endif

Просмотреть файл

@ -77,7 +77,9 @@ def CompoundLiteralExpr : DStmt<Expr>;
def ExtVectorElementExpr : DStmt<Expr>;
def InitListExpr : DStmt<Expr>;
def DesignatedInitExpr : DStmt<Expr>;
def DesignatedInitUpdateExpr : DStmt<Expr>;
def ImplicitValueInitExpr : DStmt<Expr>;
def NoInitExpr : DStmt<Expr>;
def ParenListExpr : DStmt<Expr>;
def VAArgExpr : DStmt<Expr>;
def GenericSelectionExpr : DStmt<Expr>;

Просмотреть файл

@ -16,6 +16,7 @@
#ifndef LLVM_CLANG_BASIC_TARGETBUILTINS_H
#define LLVM_CLANG_BASIC_TARGETBUILTINS_H
#include <stdint.h>
#include "clang/Basic/Builtins.h"
#undef PPC

Просмотреть файл

@ -66,6 +66,7 @@ protected:
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
unsigned char SuitableAlign;
unsigned char DefaultAlignForAttributeAligned;
unsigned char MinGlobalAlign;
unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
unsigned short MaxVectorAlign;
@ -314,6 +315,12 @@ public:
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
/// \brief Return the default alignment for __attribute__((aligned)) on
/// this target, to be used if no alignment value is specified.
unsigned getDefaultAlignForAttributeAligned() const {
return DefaultAlignForAttributeAligned;
}
/// getMinGlobalAlign - Return the minimum alignment of a global variable,
/// unless its alignment is explicitly reduced via attributes.
unsigned getMinGlobalAlign() const { return MinGlobalAlign; }
@ -356,6 +363,10 @@ public:
return *LongDoubleFormat;
}
/// \brief Return true if the 'long double' type should be mangled like
/// __float128.
virtual bool useFloat128ManglingForLongDouble() const { return false; }
/// \brief Return the value for the C99 FLT_EVAL_METHOD macro.
virtual unsigned getFloatEvalMethod() const { return 0; }

Просмотреть файл

@ -45,6 +45,8 @@ public:
/// The list of target specific features to enable or disable -- this should
/// be a list of strings starting with by '+' or '-'.
std::vector<std::string> Features;
std::vector<std::string> Reciprocals;
};
} // end namespace clang

Просмотреть файл

@ -10,7 +10,8 @@
// This file defines the TokenKind database. This includes normal tokens like
// tok::ampamp (corresponding to the && token) as well as keywords for various
// languages. Users of this file must optionally #define the TOK, KEYWORD,
// ALIAS, or PPKEYWORD macros to make use of this file.
// CXX11_KEYWORD, CONCEPTS_KEYWORD, ALIAS, or PPKEYWORD macros to make use of
// this file.
//
//===----------------------------------------------------------------------===//
@ -23,6 +24,12 @@
#ifndef KEYWORD
#define KEYWORD(X,Y) TOK(kw_ ## X)
#endif
#ifndef CXX11_KEYWORD
#define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y))
#endif
#ifndef CONCEPTS_KEYWORD
#define CONCEPTS_KEYWORD(X) KEYWORD(X,KEYCONCEPTS)
#endif
#ifndef TYPE_TRAIT
#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
#endif
@ -223,6 +230,8 @@ PUNCTUATOR(greatergreatergreater, ">>>")
// implementation namespace
// KEYNOCXX - This is a keyword in every non-C++ dialect.
// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
// KEYCONCEPTS - This is a keyword if the C++ extensions for concepts
// are enabled.
// KEYGNU - This is a keyword if GNU extensions are enabled
// KEYMS - This is a keyword if Microsoft extensions are enabled
// KEYNOMS18 - This is a keyword that must never be enabled under
@ -330,16 +339,20 @@ CXX_KEYWORD_OPERATOR(xor , caret)
CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
// C++11 keywords
KEYWORD(alignas , KEYCXX11)
KEYWORD(alignof , KEYCXX11)
KEYWORD(char16_t , KEYCXX11|KEYNOMS18)
KEYWORD(char32_t , KEYCXX11|KEYNOMS18)
KEYWORD(constexpr , KEYCXX11)
KEYWORD(decltype , KEYCXX11)
KEYWORD(noexcept , KEYCXX11)
KEYWORD(nullptr , KEYCXX11)
KEYWORD(static_assert , KEYCXX11)
KEYWORD(thread_local , KEYCXX11)
CXX11_KEYWORD(alignas , 0)
CXX11_KEYWORD(alignof , 0)
CXX11_KEYWORD(char16_t , KEYNOMS18)
CXX11_KEYWORD(char32_t , KEYNOMS18)
CXX11_KEYWORD(constexpr , 0)
CXX11_KEYWORD(decltype , 0)
CXX11_KEYWORD(noexcept , 0)
CXX11_KEYWORD(nullptr , 0)
CXX11_KEYWORD(static_assert , 0)
CXX11_KEYWORD(thread_local , 0)
// C++ concepts TS keywords
CONCEPTS_KEYWORD(concept)
CONCEPTS_KEYWORD(requires)
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
@ -455,7 +468,7 @@ KEYWORD(__private_extern__ , KEYALL)
KEYWORD(__module_private__ , KEYALL)
// Microsoft Extension.
KEYWORD(__declspec , KEYALL)
KEYWORD(__declspec , KEYMS|KEYBORLAND)
KEYWORD(__cdecl , KEYALL)
KEYWORD(__stdcall , KEYALL)
KEYWORD(__fastcall , KEYALL)
@ -735,6 +748,8 @@ ANNOTATION(module_end)
#undef TYPE_TRAIT_2
#undef TYPE_TRAIT_1
#undef TYPE_TRAIT
#undef CONCEPTS_KEYWORD
#undef CXX11_KEYWORD
#undef KEYWORD
#undef PUNCTUATOR
#undef TOK

Просмотреть файл

@ -802,6 +802,13 @@ def VREINTERPRET
def VFMA : SInst<"vfma", "dddd", "fQf">;
////////////////////////////////////////////////////////////////////////////////
// fp16 vector operations
def SCALAR_HALF_GET_LANE : IOpInst<"vget_lane", "sdi", "h", OP_SCALAR_HALF_GET_LN>;
def SCALAR_HALF_SET_LANE : IOpInst<"vset_lane", "dsdi", "h", OP_SCALAR_HALF_SET_LN>;
def SCALAR_HALF_GET_LANEQ : IOpInst<"vget_lane", "sdi", "Qh", OP_SCALAR_HALF_GET_LNQ>;
def SCALAR_HALF_SET_LANEQ : IOpInst<"vset_lane", "dsdi", "Qh", OP_SCALAR_HALF_SET_LNQ>;
////////////////////////////////////////////////////////////////////////////////
// AArch64 Intrinsics
@ -1594,10 +1601,4 @@ def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_
def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
// FIXME: Rename so it is obvious this only applies to halfs.
def SCALAR_HALF_GET_LANE : IOpInst<"vget_lane", "sdi", "h", OP_SCALAR_HALF_GET_LN>;
def SCALAR_HALF_SET_LANE : IOpInst<"vset_lane", "dsdi", "h", OP_SCALAR_HALF_SET_LN>;
def SCALAR_HALF_GET_LANEQ : IOpInst<"vget_lane", "sdi", "Qh", OP_SCALAR_HALF_GET_LNQ>;
def SCALAR_HALF_SET_LANEQ : IOpInst<"vset_lane", "dsdi", "Qh", OP_SCALAR_HALF_SET_LNQ>;
}

Просмотреть файл

@ -8,6 +8,9 @@
/* Bug report URL. */
#define BUG_REPORT_URL "${BUG_REPORT_URL}"
/* Default OpenMP runtime used by -fopenmp. */
#define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}"
/* Multilib suffix for libdir. */
#define CLANG_LIBDIR_SUFFIX "${CLANG_LIBDIR_SUFFIX}"

Просмотреть файл

@ -8,6 +8,9 @@
/* Bug report URL. */
#undef BUG_REPORT_URL
/* Default OpenMP runtime used by -fopenmp. */
#undef CLANG_DEFAULT_OPENMP_RUNTIME
/* Multilib suffix for libdir. */
#undef CLANG_LIBDIR_SUFFIX

Просмотреть файл

@ -241,6 +241,20 @@ def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">,
HelpText<"Run the BB vectorization passes">;
def dependent_lib : Joined<["--"], "dependent-lib=">,
HelpText<"Add dependent library">;
def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">,
HelpText<"Sanitizer coverage type">;
def fsanitize_coverage_indirect_calls
: Flag<["-"], "fsanitize-coverage-indirect-calls">,
HelpText<"Enable sanitizer coverage for indirect calls">;
def fsanitize_coverage_trace_bb
: Flag<["-"], "fsanitize-coverage-trace-bb">,
HelpText<"Enable basic block tracing in sanitizer coverage">;
def fsanitize_coverage_trace_cmp
: Flag<["-"], "fsanitize-coverage-trace-cmp">,
HelpText<"Enable cmp instruction tracing in sanitizer coverage">;
def fsanitize_coverage_8bit_counters
: Flag<["-"], "fsanitize-coverage-8bit-counters">,
HelpText<"Enable frequency counters in sanitizer coverage">;
//===----------------------------------------------------------------------===//
// Dependency Output Options
@ -287,6 +301,10 @@ def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">,
HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
def verify : Flag<["-"], "verify">,
HelpText<"Verify diagnostic output using comment directives">;
def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">,
HelpText<"Ignore unexpected diagnostic messages">;
def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">,
HelpText<"Ignore unexpected diagnostic messages">;
def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
HelpText<"Silence ObjC rewriting warnings">;
@ -347,6 +365,12 @@ def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">,
def fmodule_feature : Separate<["-"], "fmodule-feature">,
MetaVarName<"<feature>">,
HelpText<"Enable <feature> in module map requires declarations">;
def fmodules_local_submodule_visibility :
Flag<["-"], "fmodules-local-submodule-visibility">,
HelpText<"Enforce name visibility rules across submodules of the same "
"top-level module.">;
def fconcepts_ts : Flag<["-"], "fconcepts-ts">,
HelpText<"Enable C++ Extensions for Concepts.">;
let Group = Action_Group in {
@ -529,6 +553,8 @@ def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
HelpText<"Control vtordisp placement on win32 targets">;
def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
HelpText<"Control emission of RTTI data">;
def fnative_half_type: Flag<["-"], "fnative-half-type">,
HelpText<"Use the native half type for __fp16 instead of promoting to float">;
def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
HelpText<"Allow function arguments and returns of type half">;
@ -613,6 +639,8 @@ def fcuda_allow_host_calls_from_host_device : Flag<["-"],
def fcuda_disable_target_call_checks : Flag<["-"],
"fcuda-disable-target-call-checks">,
HelpText<"Disable all cross-target (host, device, etc.) call checks in CUDA">;
def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">,
HelpText<"Incorporate CUDA device-side binary into host object file.">;
} // let Flags = [CC1Option]

Просмотреть файл

@ -63,6 +63,8 @@ def _SLASH_fp_except_ : CLFlag<"fp:except-">, HelpText<"">, Alias<fno_trapping_m
def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias<ffast_math>;
def _SLASH_fp_precise : CLFlag<"fp:precise">, HelpText<"">, Alias<fno_fast_math>;
def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>;
def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>,
HelpText<"Assume thread-local variables are defined in the executable">;
def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">;
def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">;
def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">,
@ -137,8 +139,16 @@ def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
AliasArgs<["no-macro-redefined"]>;
def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>,
AliasArgs<["no-deprecated-declarations"]>;
def _SLASH_wd4910 : CLFlag<"wd4910">, Alias<W_Joined>,
AliasArgs<["no-dllexport-explicit-instantiation-decl"]>;
def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
Alias<vtordisp_mode_EQ>;
def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">,
HelpText<"Enable C++14 sized global deallocation functions">,
Alias<fsized_deallocation>;
def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">,
HelpText<"Disable C++14 sized global deallocation functions">,
Alias<fno_sized_deallocation>;
def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">,
HelpText<"Treat string literals as const">, Alias<W_Joined>,
AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>;
@ -210,6 +220,12 @@ def _SLASH_o : CLJoinedOrSeparate<"o">,
HelpText<"Set output file or directory (ends in / or \\)">,
MetaVarName<"<file or directory>">;
def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
def _SLASH_Qvec : CLFlag<"Qvec">,
HelpText<"Enable the loop vectorization passes">,
Alias<fvectorize>;
def _SLASH_Qvec_ : CLFlag<"Qvec-">,
HelpText<"Disable the loop vectorization passes">,
Alias<fno_vectorize>;
def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
HelpText<"Specify a C source file">, MetaVarName<"<filename>">;
def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
@ -269,7 +285,6 @@ def _SLASH_FU : CLJoinedOrSeparate<"FU">;
def _SLASH_Fx : CLFlag<"Fx">;
def _SLASH_G1 : CLFlag<"G1">;
def _SLASH_G2 : CLFlag<"G2">;
def _SLASH_GA : CLFlag<"GA">;
def _SLASH_Ge : CLFlag<"Ge">;
def _SLASH_Gh : CLFlag<"Gh">;
def _SLASH_GH : CLFlag<"GH">;

Просмотреть файл

@ -250,6 +250,8 @@ def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>,
HelpText<"Specify name of main file output to quote in depfile">;
def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,
HelpText<"Specify name of main file output in depfile">;
def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
HelpText<"Use NMake/Jom format for the depfile">;
def Mach : Flag<["-"], "Mach">;
def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;
def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;
@ -416,7 +418,10 @@ def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
Alias<fprofile_sample_use_EQ>;
def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Generate instrumented code to collect execution counts">;
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<file>">,
HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>;
def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
Group<f_Group>, Flags<[CC1Option]>,
@ -462,7 +467,7 @@ def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group>
def fdebug_pass_structure : Flag<["-"], "fdebug-pass-structure">, Group<f_Group>;
def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group<f_clang_Group>;
def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group<f_clang_Group>,
Flags<[CC1Option]>, HelpText<"Print fix-its in machine parseable form">;
Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">;
def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Print source range spans in numeric form">;
@ -524,9 +529,15 @@ def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
Group<f_clang_Group>,
HelpText<"Don't use blacklist file for sanitizers">;
def fsanitize_coverage : Joined<["-"], "fsanitize-coverage=">,
Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Enable coverage instrumentation for Sanitizers">;
def fsanitize_coverage
: CommaJoined<["-"], "fsanitize-coverage=">,
Group<f_clang_Group>, Flags<[CoreOption]>,
HelpText<"Specify the type of coverage instrumentation for Sanitizers">;
def fno_sanitize_coverage
: CommaJoined<["-"], "fno-sanitize-coverage=">,
Group<f_clang_Group>, Flags<[CoreOption]>,
HelpText<"Disable specified features of coverage instrumentation for "
"Sanitizers">;
def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enable origins tracking in MemorySanitizer">;
@ -865,7 +876,8 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Gr
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>;
def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@ -913,8 +925,8 @@ def fspell_checking : Flag<["-"], "fspell-checking">, Group<f_Group>;
def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group<f_Group>;
def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>;
def fsigned_char : Flag<["-"], "fsigned-char">, Group<f_Group>;
def fno_signed_char : Flag<["-"], "fno-signed-char">, Flags<[CC1Option]>,
Group<clang_ignored_f_Group>, HelpText<"Char is unsigned">;
def fno_signed_char : Flag<["-"], "fno-signed-char">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Char is unsigned">;
def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>;
def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
HelpText<"Force the usage of stack protectors for all functions">;
@ -995,7 +1007,7 @@ def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>,
HelpText<"Do not process trigraph sequences">, Flags<[CC1Option]>;
def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">, Group<clang_ignored_f_Group>;
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>;
def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>;
def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>,
@ -1305,6 +1317,9 @@ def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]>
def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>;
def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>;
def mvx : Flag<["-"], "mvx">, Group<m_Group>;
def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>;
def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>,
@ -1323,6 +1338,8 @@ def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]>
def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
HelpText<"Don't generate implicit floating point instructions">;
def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>;
def mrecip : Flag<["-"], "mrecip">, Group<m_Group>;
def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>;
def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>;
def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>;
@ -1567,7 +1584,7 @@ def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
"system header.">;
def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
def s : Flag<["-"], "s">;
def target : Joined<["-", "--"], "target=">, Flags<[DriverOption, CoreOption]>,
def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
HelpText<"Generate code for the given target">;
def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>,
HelpText<"Use the gcc toolchain at the given directory">;
@ -1740,7 +1757,7 @@ def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<march_EQ>,
// aliases for options that are spelled using the more common Unix / GNU flag
// style of double-dash and equals-joined flags.
def gcc_toolchain_legacy_spelling : Separate<["-"], "gcc-toolchain">, Alias<gcc_toolchain>;
def target_legacy_spelling : Separate<["-", "--"], "target">, Alias<target>;
def target_legacy_spelling : Separate<["-"], "target">, Alias<target>;
// Special internal option to handle -Xlinker --no-demangle.
def Z_Xlinker__no_demangle : Flag<["-"], "Z-Xlinker-no-demangle">,

Просмотреть файл

@ -25,7 +25,7 @@ class SanitizerArgs {
SanitizerSet RecoverableSanitizers;
std::vector<std::string> BlacklistFiles;
int SanitizeCoverage;
int CoverageFeatures;
int MsanTrackOrigins;
int AsanFieldPadding;
bool AsanZeroBaseShadow;
@ -47,6 +47,9 @@ class SanitizerArgs {
}
bool needsUbsanRt() const;
bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
bool needsSafeStackRt() const {
return Sanitizers.has(SanitizerKind::SafeStack);
}
bool requiresPIE() const;
bool needsUnwindTables() const;

Просмотреть файл

@ -164,7 +164,10 @@ public:
}
/// Choose a tool to use to handle the action \p JA.
Tool *SelectTool(const JobAction &JA) const;
///
/// This can be overridden when a particular ToolChain needs to use
/// a C compiler other than Clang.
virtual Tool *SelectTool(const JobAction &JA) const;
// Helper methods

Просмотреть файл

@ -55,14 +55,14 @@ TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", "u")
// C family input files to precompile.
TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p")
TYPE("c-header", CHeader, PP_CHeader, nullptr, "pu")
TYPE("cl-header", CLHeader, PP_CHeader, nullptr, "pu")
TYPE("c-header", CHeader, PP_CHeader, "h", "pu")
TYPE("cl-header", CLHeader, PP_CHeader, "h", "pu")
TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", "p")
TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, nullptr, "pu")
TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, "h", "pu")
TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p")
TYPE("c++-header", CXXHeader, PP_CXXHeader, nullptr, "pu")
TYPE("c++-header", CXXHeader, PP_CXXHeader, "hh", "pu")
TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, nullptr, "pu")
TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, "h", "pu")
// Other languages.
TYPE("ada", Ada, INVALID, nullptr, "u")

Просмотреть файл

@ -210,10 +210,10 @@ struct FormatStyle {
enum ShortFunctionStyle {
/// \brief Never merge functions into a single line.
SFS_None,
/// \brief Only merge functions defined inside a class.
SFS_Inline,
/// \brief Only merge empty functions.
SFS_Empty,
/// \brief Only merge functions defined inside a class. Implies "empty".
SFS_Inline,
/// \brief Merge all functions fitting on a single line.
SFS_All,
};
@ -247,6 +247,17 @@ struct FormatStyle {
/// \brief If \c true, aligns trailing comments.
bool AlignTrailingComments;
/// \brief If \c true, aligns consecutive assignments.
///
/// This will align the assignment operators of consecutive lines. This
/// will result in formattings like
/// \code
/// int aaaa = 12;
/// int b = 23;
/// int ccc = 23;
/// \endcode
bool AlignConsecutiveAssignments;
/// \brief If \c true, aligns escaped newlines as far left as possible.
/// Otherwise puts them into the right-most column.
bool AlignEscapedNewlinesLeft;
@ -527,14 +538,6 @@ std::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
/// \brief Gets configuration in a YAML string.
std::string configurationAsText(const FormatStyle &Style);
/// \brief Reformats the given \p Ranges in the token stream coming out of
/// \c Lex.
///
/// DEPRECATED: Do not use.
tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
SourceManager &SourceMgr,
ArrayRef<CharSourceRange> Ranges);
/// \brief Reformats the given \p Ranges in the file \p ID.
///
/// Each range is extended on either end to its next bigger logic unit, i.e.
@ -543,16 +546,22 @@ tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
///
/// Returns the \c Replacements necessary to make all \p Ranges comply with
/// \p Style.
///
/// If \c IncompleteFormat is non-null, its value will be set to true if any
/// of the affected ranges were not formatted due to a non-recoverable syntax
/// error.
tooling::Replacements reformat(const FormatStyle &Style,
SourceManager &SourceMgr, FileID ID,
ArrayRef<CharSourceRange> Ranges);
ArrayRef<CharSourceRange> Ranges,
bool *IncompleteFormat = nullptr);
/// \brief Reformats the given \p Ranges in \p Code.
///
/// Otherwise identical to the reformat() function consuming a \c Lexer.
/// Otherwise identical to the reformat() function using a file ID.
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>");
StringRef FileName = "<stdin>",
bool *IncompleteFormat = nullptr);
/// \brief Returns the \c LangOpts that the formatter expects you to set.
///

Просмотреть файл

@ -880,7 +880,7 @@ public:
}
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
SourceLocation ImportLoc, bool Complain) override {}
SourceLocation ImportLoc) override {}
GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
{ return nullptr; }

Просмотреть файл

@ -110,7 +110,16 @@ CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
///< offset in AddressSanitizer.
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
///< MemorySanitizer
CODEGENOPT(SanitizeCoverage, 3, 0) ///< Enable sanitizer coverage instrumentation.
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
///< instrumentation.
CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage
///< for indirect calls.
CODEGENOPT(SanitizeCoverageTraceBB, 1, 0) ///< Enable basic block tracing in
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters
///< in sanitizer coverage.
CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
/// -fsanitize-undefined-trap-on-error
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.

Просмотреть файл

@ -154,12 +154,20 @@ public:
/// A list of dependent libraries.
std::vector<std::string> DependentLibraries;
/// Name of the profile file to use as output for -fprofile-instr-generate
std::string InstrProfileOutput;
/// Name of the profile file to use with -fprofile-sample-use.
std::string SampleProfileFile;
/// Name of the profile file to use as input for -fprofile-instr-use
std::string InstrProfileInput;
/// A list of file names passed with -fcuda-include-gpubinary options to
/// forward to CUDA runtime back-end for incorporating them into host-side
/// object file.
std::vector<std::string> CudaGpuBinaryFileNames;
/// Regular expression to select optimizations for which we should enable
/// optimization remarks. Transformation passes whose name matches this
/// expression (and support this feature), will emit a diagnostic

Просмотреть файл

@ -716,7 +716,7 @@ public:
bool IsInclusionDirective) override;
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
SourceLocation ImportLoc, bool Complain) override;
SourceLocation ImportLoc) override;
bool hadModuleLoaderFatalFailure() const {
return ModuleLoader::HadFatalFailure;

Просмотреть файл

@ -15,6 +15,9 @@
namespace clang {
/// DependencyOutputFormat - Format for the compiler dependency file.
enum class DependencyOutputFormat { Make, NMake };
/// DependencyOutputOptions - Options for controlling the compiler dependency
/// file generation.
class DependencyOutputOptions {
@ -27,7 +30,10 @@ public:
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
/// The format for the dependency file.
DependencyOutputFormat OutputFormat;
/// The file to write dependency output to.
std::string OutputFile;
@ -55,6 +61,7 @@ public:
AddMissingHeaderDeps = 0;
PrintShowIncludes = 0;
IncludeModuleFiles = 0;
OutputFormat = DependencyOutputFormat::Make;
}
};

Просмотреть файл

@ -15,7 +15,7 @@
namespace clang {
class Decl;
class MacroDefinition;
class MacroDefinitionRecord;
class SourceManager;
namespace index {
@ -52,8 +52,8 @@ void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
/// \brief Generate a USR for a macro, including the USR prefix.
///
/// \returns true on error, false on success.
bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM,
SmallVectorImpl<char> &Buf);
bool generateUSRForMacro(const MacroDefinitionRecord *MD,
const SourceManager &SM, SmallVectorImpl<char> &Buf);
} // namespace index
} // namespace clang

Просмотреть файл

@ -17,6 +17,7 @@
namespace clang {
class IdentifierInfo;
class Module;
/// \brief Abstract interface for external sources of preprocessor
/// information.
@ -32,6 +33,9 @@ public:
/// \brief Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
/// \brief Map a module ID to a module.
virtual Module *getModule(unsigned ModuleID) = 0;
};
}

Просмотреть файл

@ -32,6 +32,7 @@ class FileEntry;
class FileManager;
class HeaderSearchOptions;
class IdentifierInfo;
class Preprocessor;
/// \brief The preprocessor keeps track of this information for each
/// file that is \#included.
@ -419,8 +420,8 @@ public:
///
/// \return false if \#including the file will have no effect or true
/// if we should include it.
bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
bool isImport);
/// \brief Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.
@ -478,9 +479,6 @@ public:
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
/// Returns true if modules are enabled.
bool enabledModules() const { return LangOpts.Modules; }
/// \brief Retrieve the name of the module file that should be used to
/// load the given module.
///

Просмотреть файл

@ -180,14 +180,14 @@ public:
/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
bool IsFramework, bool IgnoreSysRoot) {
UserEntries.push_back(Entry(Path, Group, IsFramework, IgnoreSysRoot));
UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot);
}
/// AddSystemHeaderPrefix - Override whether \#include directives naming a
/// path starting with \p Prefix should be considered as naming a system
/// header.
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
SystemHeaderPrefixes.push_back(SystemHeaderPrefix(Prefix, IsSystemHeader));
SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
}
void AddVFSOverlayFile(StringRef Name) {

Просмотреть файл

@ -228,7 +228,7 @@ public:
/// Stringify - Convert the specified string into a C string by escaping '\'
/// and " characters. This does not add surrounding ""'s to the string.
/// If Charify is true, this escapes the ' character instead of ".
static std::string Stringify(const std::string &Str, bool Charify = false);
static std::string Stringify(StringRef Str, bool Charify = false);
/// Stringify - Convert the specified string into a C string by escaping '\'
/// and " characters. This does not add surrounding ""'s to the string.

Просмотреть файл

@ -17,11 +17,15 @@
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
namespace clang {
class Module;
class ModuleMacro;
class Preprocessor;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
@ -40,8 +44,8 @@ class MacroInfo {
///
/// ArgumentList points to the first of NumArguments pointers.
///
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic macro, this
/// includes the \c __VA_ARGS__ identifier on the list.
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
IdentifierInfo **ArgumentList;
/// \see ArgumentList
@ -66,15 +70,15 @@ class MacroInfo {
/// \brief True if this macro is of the form "#define X(a...)".
///
/// The "a" identifier in the replacement list will be replaced with all arguments
/// of the macro starting with the specified one.
/// The "a" identifier in the replacement list will be replaced with all
/// arguments of the macro starting with the specified one.
bool IsGNUVarargs : 1;
/// \brief True if this macro requires processing before expansion.
///
/// This is the case for builtin macros such as __LINE__, so long as they have
/// not been redefined, but not for regular predefined macros from the "<built-in>"
/// memory buffer (see Preprocessing::getPredefinesFileID).
/// not been redefined, but not for regular predefined macros from the
/// "<built-in>" memory buffer (see Preprocessing::getPredefinesFileID).
bool IsBuiltinMacro : 1;
/// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
@ -139,14 +143,10 @@ public:
bool Syntactically) const;
/// \brief Set or clear the isBuiltinMacro flag.
void setIsBuiltinMacro(bool Val = true) {
IsBuiltinMacro = Val;
}
void setIsBuiltinMacro(bool Val = true) { IsBuiltinMacro = Val; }
/// \brief Set the value of the IsUsed flag.
void setIsUsed(bool Val) {
IsUsed = Val;
}
void setIsUsed(bool Val) { IsUsed = Val; }
/// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
void setIsAllowRedefinitionsWithoutWarning(bool Val) {
@ -154,37 +154,40 @@ public:
}
/// \brief Set the value of the IsWarnIfUnused flag.
void setIsWarnIfUnused(bool val) {
IsWarnIfUnused = val;
}
void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
/// \brief Set the specified list of identifiers as the argument list for
/// this macro.
void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
void setArgumentList(IdentifierInfo *const *List, unsigned NumArgs,
llvm::BumpPtrAllocator &PPAllocator) {
assert(ArgumentList == nullptr && NumArguments == 0 &&
"Argument list already set!");
if (NumArgs == 0) return;
if (NumArgs == 0)
return;
NumArguments = NumArgs;
ArgumentList = PPAllocator.Allocate<IdentifierInfo*>(NumArgs);
ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(NumArgs);
for (unsigned i = 0; i != NumArgs; ++i)
ArgumentList[i] = List[i];
}
/// Arguments - The list of arguments for a function-like macro. This can be
/// empty, for, e.g. "#define X()".
typedef IdentifierInfo* const *arg_iterator;
typedef IdentifierInfo *const *arg_iterator;
bool arg_empty() const { return NumArguments == 0; }
arg_iterator arg_begin() const { return ArgumentList; }
arg_iterator arg_end() const { return ArgumentList+NumArguments; }
arg_iterator arg_end() const { return ArgumentList + NumArguments; }
unsigned getNumArgs() const { return NumArguments; }
ArrayRef<const IdentifierInfo *> args() const {
return ArrayRef<const IdentifierInfo *>(ArgumentList, NumArguments);
}
/// \brief Return the argument number of the specified identifier,
/// or -1 if the identifier is not a formal argument identifier.
int getArgumentNum(IdentifierInfo *Arg) const {
int getArgumentNum(const IdentifierInfo *Arg) const {
for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
if (*I == Arg) return I-arg_begin();
if (*I == Arg)
return I - arg_begin();
return -1;
}
@ -222,15 +225,11 @@ public:
}
/// \brief Return true if we should emit a warning if the macro is unused.
bool isWarnIfUnused() const {
return IsWarnIfUnused;
}
bool isWarnIfUnused() const { return IsWarnIfUnused; }
/// \brief Return the number of tokens that this macro expands to.
///
unsigned getNumTokens() const {
return ReplacementTokens.size();
}
unsigned getNumTokens() const { return ReplacementTokens.size(); }
const Token &getReplacementToken(unsigned Tok) const {
assert(Tok < ReplacementTokens.size() && "Invalid token #");
@ -241,11 +240,13 @@ public:
tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
ArrayRef<Token> tokens() const { return ReplacementTokens; }
/// \brief Add the specified token to the replacement text for the macro.
void AddTokenToBody(const Token &Tok) {
assert(!IsDefinitionLengthCached &&
"Changing replacement tokens after definition length got calculated");
assert(
!IsDefinitionLengthCached &&
"Changing replacement tokens after definition length got calculated");
ReplacementTokens.push_back(Tok);
}
@ -277,7 +278,7 @@ public:
/// macro info.
unsigned getOwningModuleID() const {
if (isFromASTFile())
return *(const unsigned*)(this+1);
return *(const unsigned *)(this + 1);
return 0;
}
@ -289,7 +290,7 @@ private:
void setOwningModuleID(unsigned ID) {
assert(isFromASTFile());
*(unsigned*)(this+1) = ID;
*(unsigned *)(this + 1) = ID;
}
friend class Preprocessor;
@ -302,22 +303,11 @@ class DefMacroDirective;
///
/// MacroDirectives, associated with an identifier, are used to model the macro
/// history. Usually a macro definition (MacroInfo) is where a macro name
/// becomes active (MacroDirective) but modules can have their own macro
/// history, separate from the local (current translation unit) macro history.
///
/// For example, if "@import A;" imports macro FOO, there will be a new local
/// MacroDirective created to indicate that "FOO" became active at the import
/// location. Module "A" itself will contain another MacroDirective in its macro
/// history (at the point of the definition of FOO) and both MacroDirectives
/// will point to the same MacroInfo object.
///
/// becomes active (MacroDirective) but #pragma push_macro / pop_macro can
/// create additional DefMacroDirectives for the same MacroInfo.
class MacroDirective {
public:
enum Kind {
MD_Define,
MD_Undefine,
MD_Visibility
};
enum Kind { MD_Define, MD_Undefine, MD_Visibility };
protected:
/// \brief Previous macro directive for the same identifier, or NULL.
@ -331,47 +321,15 @@ protected:
/// \brief True if the macro directive was loaded from a PCH file.
bool IsFromPCH : 1;
// Used by DefMacroDirective -----------------------------------------------//
/// \brief Whether the definition of this macro is ambiguous, due to
/// multiple definitions coming in from multiple modules.
bool IsAmbiguous : 1;
// Used by VisibilityMacroDirective ----------------------------------------//
/// \brief Whether the macro has public visibility (when described in a
/// module).
bool IsPublic : 1;
// Used by DefMacroDirective and UndefMacroDirective -----------------------//
/// \brief True if this macro was imported from a module.
bool IsImported : 1;
/// \brief For an imported directive, the number of modules whose macros are
/// overridden by this directive. Only used if IsImported.
unsigned NumOverrides : 26;
unsigned *getModuleDataStart();
const unsigned *getModuleDataStart() const {
return const_cast<MacroDirective*>(this)->getModuleDataStart();
}
MacroDirective(Kind K, SourceLocation Loc,
unsigned ImportedFromModuleID = 0,
ArrayRef<unsigned> Overrides = None)
MacroDirective(Kind K, SourceLocation Loc)
: Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
IsAmbiguous(false), IsPublic(true), IsImported(ImportedFromModuleID),
NumOverrides(Overrides.size()) {
assert(NumOverrides == Overrides.size() && "too many overrides");
assert((IsImported || !NumOverrides) && "overrides for non-module macro");
if (IsImported) {
unsigned *Extra = getModuleDataStart();
*Extra++ = ImportedFromModuleID;
std::copy(Overrides.begin(), Overrides.end(), Extra);
}
}
IsPublic(true) {}
public:
Kind getKind() const { return Kind(MDKind); }
@ -379,9 +337,7 @@ public:
SourceLocation getLocation() const { return Loc; }
/// \brief Set previous definition of the macro with the same name.
void setPrevious(MacroDirective *Prev) {
Previous = Prev;
}
void setPrevious(MacroDirective *Prev) { Previous = Prev; }
/// \brief Get previous definition of the macro with the same name.
const MacroDirective *getPrevious() const { return Previous; }
@ -394,46 +350,25 @@ public:
void setIsFromPCH() { IsFromPCH = true; }
/// \brief True if this macro was imported from a module.
/// Note that this is never the case for a VisibilityMacroDirective.
bool isImported() const { return IsImported; }
/// \brief If this directive was imported from a module, get the submodule
/// whose directive this is. Note that this may be different from the module
/// that owns the MacroInfo for a DefMacroDirective due to #pragma pop_macro
/// and similar effects.
unsigned getOwningModuleID() const {
if (isImported())
return *getModuleDataStart();
return 0;
}
/// \brief Get the module IDs of modules whose macros are overridden by this
/// directive. Only valid if this is an imported directive.
ArrayRef<unsigned> getOverriddenModules() const {
assert(IsImported && "can only get overridden modules for imported macro");
return llvm::makeArrayRef(getModuleDataStart() + 1, NumOverrides);
}
class DefInfo {
DefMacroDirective *DefDirective;
SourceLocation UndefLoc;
bool IsPublic;
public:
DefInfo() : DefDirective(nullptr) { }
DefInfo() : DefDirective(nullptr), IsPublic(true) {}
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
bool isPublic)
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {}
const DefMacroDirective *getDirective() const { return DefDirective; }
DefMacroDirective *getDirective() { return DefDirective; }
DefMacroDirective *getDirective() { return DefDirective; }
inline SourceLocation getLocation() const;
inline MacroInfo *getMacroInfo();
const MacroInfo *getMacroInfo() const {
return const_cast<DefInfo*>(this)->getMacroInfo();
return const_cast<DefInfo *>(this)->getMacroInfo();
}
SourceLocation getUndefLocation() const { return UndefLoc; }
@ -448,7 +383,7 @@ public:
inline DefInfo getPreviousDefinition();
const DefInfo getPreviousDefinition() const {
return const_cast<DefInfo*>(this)->getPreviousDefinition();
return const_cast<DefInfo *>(this)->getPreviousDefinition();
}
};
@ -457,7 +392,7 @@ public:
/// (if there is one) and if it is public or private.
DefInfo getDefinition();
const DefInfo getDefinition() const {
return const_cast<MacroDirective*>(this)->getDefinition();
return const_cast<MacroDirective *>(this)->getDefinition();
}
bool isDefined() const {
@ -469,9 +404,7 @@ public:
const MacroInfo *getMacroInfo() const {
return getDefinition().getMacroInfo();
}
MacroInfo *getMacroInfo() {
return getDefinition().getMacroInfo();
}
MacroInfo *getMacroInfo() { return getDefinition().getMacroInfo(); }
/// \brief Find macro definition active in the specified source location. If
/// this macro was not defined there, return NULL.
@ -487,30 +420,17 @@ class DefMacroDirective : public MacroDirective {
MacroInfo *Info;
public:
DefMacroDirective(MacroInfo *MI, SourceLocation Loc)
: MacroDirective(MD_Define, Loc), Info(MI) {
assert(MI && "MacroInfo is null");
}
explicit DefMacroDirective(MacroInfo *MI)
: MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
assert(MI && "MacroInfo is null");
}
DefMacroDirective(MacroInfo *MI, SourceLocation Loc,
unsigned ImportedFromModuleID = 0,
ArrayRef<unsigned> Overrides = None)
: MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides),
Info(MI) {
assert(MI && "MacroInfo is null");
}
: DefMacroDirective(MI, MI->getDefinitionLoc()) {}
/// \brief The data for the macro definition.
const MacroInfo *getInfo() const { return Info; }
MacroInfo *getInfo() { return Info; }
/// \brief Determine whether this macro definition is ambiguous with
/// other macro definitions.
bool isAmbiguous() const { return IsAmbiguous; }
/// \brief Set whether this macro definition is ambiguous.
void setAmbiguous(bool Val) { IsAmbiguous = Val; }
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Define;
}
@ -518,13 +438,11 @@ public:
};
/// \brief A directive for an undefined macro.
class UndefMacroDirective : public MacroDirective {
class UndefMacroDirective : public MacroDirective {
public:
explicit UndefMacroDirective(SourceLocation UndefLoc,
unsigned ImportedFromModuleID = 0,
ArrayRef<unsigned> Overrides = None)
: MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) {
assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!");
explicit UndefMacroDirective(SourceLocation UndefLoc)
: MacroDirective(MD_Undefine, UndefLoc) {
assert(UndefLoc.isValid() && "Invalid UndefLoc!");
}
static bool classof(const MacroDirective *MD) {
@ -534,10 +452,10 @@ public:
};
/// \brief A directive for setting the module visibility of a macro.
class VisibilityMacroDirective : public MacroDirective {
class VisibilityMacroDirective : public MacroDirective {
public:
explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
: MacroDirective(MD_Visibility, Loc) {
: MacroDirective(MD_Visibility, Loc) {
IsPublic = Public;
}
@ -551,13 +469,6 @@ public:
static bool classof(const VisibilityMacroDirective *) { return true; }
};
inline unsigned *MacroDirective::getModuleDataStart() {
if (auto *Def = dyn_cast<DefMacroDirective>(this))
return reinterpret_cast<unsigned*>(Def + 1);
else
return reinterpret_cast<unsigned*>(cast<UndefMacroDirective>(this) + 1);
}
inline SourceLocation MacroDirective::DefInfo::getLocation() const {
if (isInvalid())
return SourceLocation();
@ -577,6 +488,123 @@ MacroDirective::DefInfo::getPreviousDefinition() {
return DefDirective->getPrevious()->getDefinition();
}
} // end namespace clang
/// \brief Represents a macro directive exported by a module.
///
/// There's an instance of this class for every macro #define or #undef that is
/// the final directive for a macro name within a module. These entities also
/// represent the macro override graph.
///
/// These are stored in a FoldingSet in the preprocessor.
class ModuleMacro : public llvm::FoldingSetNode {
/// The name defined by the macro.
IdentifierInfo *II;
/// The body of the #define, or nullptr if this is a #undef.
MacroInfo *Macro;
/// The module that exports this macro.
Module *OwningModule;
/// The number of module macros that override this one.
unsigned NumOverriddenBy;
/// The number of modules whose macros are directly overridden by this one.
unsigned NumOverrides;
// ModuleMacro *OverriddenMacros[NumOverrides];
friend class Preprocessor;
ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides)
: II(II), Macro(Macro), OwningModule(OwningModule), NumOverriddenBy(0),
NumOverrides(Overrides.size()) {
std::copy(Overrides.begin(), Overrides.end(),
reinterpret_cast<ModuleMacro **>(this + 1));
}
public:
static ModuleMacro *create(Preprocessor &PP, Module *OwningModule,
IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides);
void Profile(llvm::FoldingSetNodeID &ID) const {
return Profile(ID, OwningModule, II);
}
static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
IdentifierInfo *II) {
ID.AddPointer(OwningModule);
ID.AddPointer(II);
}
/// Get the ID of the module that exports this macro.
Module *getOwningModule() const { return OwningModule; }
/// Get definition for this exported #define, or nullptr if this
/// represents a #undef.
MacroInfo *getMacroInfo() const { return Macro; }
/// Iterators over the overridden module IDs.
/// \{
typedef ModuleMacro *const *overrides_iterator;
overrides_iterator overrides_begin() const {
return reinterpret_cast<overrides_iterator>(this + 1);
}
overrides_iterator overrides_end() const {
return overrides_begin() + NumOverrides;
}
ArrayRef<ModuleMacro *> overrides() const {
return llvm::makeArrayRef(overrides_begin(), overrides_end());
}
/// \}
/// Get the number of macros that override this one.
unsigned getNumOverridingMacros() const { return NumOverriddenBy; }
};
/// \brief A description of the current definition of a macro.
///
/// The definition of a macro comprises a set of (at least one) defining
/// entities, which are either local MacroDirectives or imported ModuleMacros.
class MacroDefinition {
llvm::PointerIntPair<DefMacroDirective *, 1, bool> LatestLocalAndAmbiguous;
ArrayRef<ModuleMacro *> ModuleMacros;
public:
MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
bool IsAmbiguous)
: LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
/// \brief Determine whether there is a definition of this macro.
explicit operator bool() const {
return getLocalDirective() || !ModuleMacros.empty();
}
/// \brief Get the MacroInfo that should be used for this definition.
MacroInfo *getMacroInfo() const {
if (!ModuleMacros.empty())
return ModuleMacros.back()->getMacroInfo();
if (auto *MD = getLocalDirective())
return MD->getMacroInfo();
return nullptr;
}
/// \brief \c true if the definition is ambiguous, \c false otherwise.
bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); }
/// \brief Get the latest non-imported, non-\#undef'd macro definition
/// for this macro.
DefMacroDirective *getLocalDirective() const {
return LatestLocalAndAmbiguous.getPointer();
}
/// \brief Get the active module macros for this macro.
ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; }
template <typename Fn> void forAllDefinitions(Fn F) const {
if (auto *MD = getLocalDirective())
F(MD->getMacroInfo());
for (auto *MM : getModuleMacros())
F(MM->getMacroInfo());
}
};
} // end namespace clang
#endif

Просмотреть файл

@ -99,8 +99,7 @@ public:
/// \brief Make the given module visible.
virtual void makeModuleVisible(Module *Mod,
Module::NameVisibilityKind Visibility,
SourceLocation ImportLoc,
bool Complain) = 0;
SourceLocation ImportLoc) = 0;
/// \brief Load, create, or return global module.
/// This function returns an existing global module index, if one

Просмотреть файл

@ -64,6 +64,9 @@ private:
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
/// \brief The number of modules we have created in total.
unsigned NumCreatedModules;
public:
/// \brief Flags describing the role of a module header.
enum ModuleHeaderRole {
@ -265,20 +268,10 @@ public:
///
/// \param File The header file that is likely to be included.
///
/// \param RequestingModule Specifies the module the header is intended to be
/// used from. Used to disambiguate if a header is present in multiple
/// modules.
///
/// \param IncludeTextualHeaders If \c true, also find textual headers. By
/// default, these are treated like excluded headers and result in no known
/// header being found.
///
/// \returns The module KnownHeader, which provides the module that owns the
/// given header file. The KnownHeader is default constructed to indicate
/// that no module owns this header file.
KnownHeader findModuleForHeader(const FileEntry *File,
Module *RequestingModule = nullptr,
bool IncludeTextualHeaders = false);
KnownHeader findModuleForHeader(const FileEntry *File);
/// \brief Reports errors if a module must not include a specific file.
///
@ -434,11 +427,13 @@ public:
/// \brief Sets the umbrella header of the given module to the given
/// header.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader);
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
Twine NameAsWritten);
/// \brief Sets the umbrella directory of the given module to the given
/// directory.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir);
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
Twine NameAsWritten);
/// \brief Adds this header to the given module.
/// \param Role The role of the header wrt the module.

Просмотреть файл

@ -27,6 +27,7 @@ namespace clang {
class SourceLocation;
class Token;
class IdentifierInfo;
class MacroDefinition;
class MacroDirective;
class MacroArgs;
@ -54,11 +55,12 @@ public:
/// \brief Callback invoked whenever a source file is skipped as the result
/// of header guard optimization.
///
/// \param ParentFile The file that \#included the skipped file.
/// \param SkippedFile The file that is skipped instead of entering \#include
///
/// \param FilenameTok The token in ParentFile that indicates the
/// skipped file.
virtual void FileSkipped(const FileEntry &ParentFile,
/// \param FilenameTok The file name token in \#include "FileName" directive
/// or macro expanded file name token from \#include MACRO(PARAMS) directive.
/// Note that FilenameTok contains corresponding quotes/angles symbols.
virtual void FileSkipped(const FileEntry &SkippedFile,
const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) {
}
@ -153,7 +155,7 @@ public:
/// \param Loc The location of the directive.
/// \param str The text of the directive.
///
virtual void Ident(SourceLocation Loc, const std::string &str) {
virtual void Ident(SourceLocation Loc, StringRef str) {
}
/// \brief Callback invoked when start reading any pragma directive.
@ -163,14 +165,13 @@ public:
/// \brief Callback invoked when a \#pragma comment directive is read.
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
const std::string &Str) {
StringRef Str) {
}
/// \brief Callback invoked when a \#pragma detect_mismatch directive is
/// read.
virtual void PragmaDetectMismatch(SourceLocation Loc,
const std::string &Name,
const std::string &Value) {
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
StringRef Value) {
}
/// \brief Callback invoked when a \#pragma clang __debug directive is read.
@ -238,9 +239,9 @@ public:
/// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range, const MacroArgs *Args) {
}
virtual void MacroExpands(const Token &MacroNameTok,
const MacroDefinition &MD, SourceRange Range,
const MacroArgs *Args) {}
/// \brief Hook called whenever a macro definition is seen.
virtual void MacroDefined(const Token &MacroNameTok,
@ -251,12 +252,12 @@ public:
///
/// MD is released immediately following this callback.
virtual void MacroUndefined(const Token &MacroNameTok,
const MacroDirective *MD) {
const MacroDefinition &MD) {
}
/// \brief Hook called whenever the 'defined' operator is seen.
/// \param MD The MacroDirective if the name was a macro, null otherwise.
virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) {
}
@ -293,17 +294,17 @@ public:
/// \brief Hook called whenever an \#ifdef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
/// \param MD The MacroDirective if the name was a macro, null otherwise.
/// \param MD The MacroDefinition if the name was a macro, null otherwise.
virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) {
const MacroDefinition &MD) {
}
/// \brief Hook called whenever an \#ifndef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
/// \param MD The MacroDirective if the name was a macro, null otherwise.
/// \param MD The MacroDefiniton if the name was a macro, null otherwise.
virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) {
const MacroDefinition &MD) {
}
/// \brief Hook called whenever an \#else is seen.
@ -336,11 +337,11 @@ public:
Second->FileChanged(Loc, Reason, FileType, PrevFID);
}
void FileSkipped(const FileEntry &ParentFile,
void FileSkipped(const FileEntry &SkippedFile,
const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) override {
First->FileSkipped(ParentFile, FilenameTok, FileType);
Second->FileSkipped(ParentFile, FilenameTok, FileType);
First->FileSkipped(SkippedFile, FilenameTok, FileType);
Second->FileSkipped(SkippedFile, FilenameTok, FileType);
}
bool FileNotFound(StringRef FileName,
@ -373,19 +374,19 @@ public:
Second->EndOfMainFile();
}
void Ident(SourceLocation Loc, const std::string &str) override {
void Ident(SourceLocation Loc, StringRef str) override {
First->Ident(Loc, str);
Second->Ident(Loc, str);
}
void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
const std::string &Str) override {
StringRef Str) override {
First->PragmaComment(Loc, Kind, Str);
Second->PragmaComment(Loc, Kind, Str);
}
void PragmaDetectMismatch(SourceLocation Loc, const std::string &Name,
const std::string &Value) override {
void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
StringRef Value) override {
First->PragmaDetectMismatch(Loc, Name, Value);
Second->PragmaDetectMismatch(Loc, Name, Value);
}
@ -434,7 +435,7 @@ public:
Second->PragmaWarningPop(Loc);
}
void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override {
First->MacroExpands(MacroNameTok, MD, Range, Args);
Second->MacroExpands(MacroNameTok, MD, Range, Args);
@ -446,12 +447,12 @@ public:
}
void MacroUndefined(const Token &MacroNameTok,
const MacroDirective *MD) override {
const MacroDefinition &MD) override {
First->MacroUndefined(MacroNameTok, MD);
Second->MacroUndefined(MacroNameTok, MD);
}
void Defined(const Token &MacroNameTok, const MacroDirective *MD,
void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override {
First->Defined(MacroNameTok, MD, Range);
Second->Defined(MacroNameTok, MD, Range);
@ -478,14 +479,14 @@ public:
/// \brief Hook called whenever an \#ifdef is seen.
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) override {
const MacroDefinition &MD) override {
First->Ifdef(Loc, MacroNameTok, MD);
Second->Ifdef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#ifndef is seen.
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) override {
const MacroDefinition &MD) override {
First->Ifndef(Loc, MacroNameTok, MD);
Second->Ifndef(Loc, MacroNameTok, MD);
}

Просмотреть файл

@ -91,9 +91,9 @@ private:
void Elif(SourceLocation Loc, SourceRange ConditionRange,
ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) override;
const MacroDefinition &MD) override;
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) override;
const MacroDefinition &MD) override;
void Else(SourceLocation Loc, SourceLocation IfLoc) override;
void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
};

Просмотреть файл

@ -129,7 +129,7 @@ public:
/// Create - This method creates PTHManager objects. The 'file' argument
/// is the name of the PTH file. This method returns NULL upon failure.
static PTHManager *Create(const std::string& file, DiagnosticsEngine &Diags);
static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags);
void setPreprocessor(Preprocessor *pp) { PP = pp; }

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше