//==--- AttrDocs.td - Attribute documentation ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//

// To test that the documentation builds cleanly, you must run clang-tblgen to
// convert the .td file into a .rst file, and then run sphinx to convert the
// .rst file into an HTML file. After completing testing, you should revert the
// generated .rst file so that the modified version does not get checked in to
// version control.
//
// To run clang-tblgen to generate the .rst file:
// clang-tblgen -gen-attr-docs -I <root>/llvm/tools/clang/include
//   <root>/llvm/tools/clang/include/clang/Basic/Attr.td -o
//   <root>/llvm/tools/clang/docs/AttributeReference.rst
//
// To run sphinx to generate the .html files (note that sphinx-build must be
// available on the PATH):
// Windows (from within the clang\docs directory):
//   make.bat html
// Non-Windows (from within the clang\docs directory):
//   make -f Makefile.sphinx html

def GlobalDocumentation {
  code Intro =[{..
  -------------------------------------------------------------------
  NOTE: This file is automatically generated by running clang-tblgen
  -gen-attr-docs. Do not edit this file by hand!!
  -------------------------------------------------------------------

===================
Attributes in Clang
===================
.. contents::
   :local:

.. |br| raw:: html

  <br/>

Introduction
============

This page lists the attributes currently supported by Clang.
}];
}

def SectionDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``section`` attribute allows you to specify a specific section a
global variable or function should be in after translation.
  }];
  let Heading = "section, __declspec(allocate)";
}

def UsedDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
This attribute, when attached to a function or variable definition, indicates
that there may be references to the entity which are not apparent in the source
code.  For example, it may be referenced from inline ``asm``, or it may be
found through a dynamic symbol or section lookup.

The compiler must emit the definition even if it appears to be unused, and it
must not apply optimizations which depend on fully understanding how the entity
is used.

Whether this attribute has any effect on the linker depends on the target and
the linker. Most linkers support the feature of section garbage collection
(``--gc-sections``), also known as "dead stripping" (``ld64 -dead_strip``) or
discarding unreferenced sections (``link.exe /OPT:REF``). On COFF and Mach-O
targets (Windows and Apple platforms), the `used` attribute prevents symbols
from being removed by linker section GC. On ELF targets, it has no effect on its
own, and the linker may remove the definition if it is not otherwise referenced.
This linker GC can be avoided by also adding the ``retain`` attribute.  Note
that ``retain`` requires special support from the linker; see that attribute's
documentation for further information.
  }];
}

def RetainDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
This attribute, when attached to a function or variable definition, prevents
section garbage collection in the linker. It does not prevent other discard
mechanisms, such as archive member selection, and COMDAT group resolution.

If the compiler does not emit the definition, e.g. because it was not used in
the translation unit or the compiler was able to eliminate all of the uses,
this attribute has no effect.  This attribute is typically combined with the
``used`` attribute to force the definition to be emitted and preserved into the
final linked image.

This attribute is only necessary on ELF targets; other targets prevent section
garbage collection by the linker when using the ``used`` attribute alone.
Using the attributes together should result in consistent behavior across
targets.

This attribute requires the linker to support the ``SHF_GNU_RETAIN`` extension.
This support is available in GNU ``ld`` and ``gold`` as of binutils 2.36, as
well as in ``ld.lld`` 13.
  }];
}

def InitPriorityDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
In C++, the order in which global variables are initialized across translation
units is unspecified, unlike the ordering within a single translation unit. The
``init_priority`` attribute allows you to specify a relative ordering for the
initialization of objects declared at namespace scope in C++. The priority is
given as an integer constant expression between 101 and 65535 (inclusive).
Priorities outside of that range are reserved for use by the implementation. A
lower value indicates a higher priority of initialization. Note that only the
relative ordering of values is important. For example:

.. code-block:: c++

  struct SomeType { SomeType(); };
  __attribute__((init_priority(200))) SomeType Obj1;
  __attribute__((init_priority(101))) SomeType Obj2;

``Obj2`` will be initialized *before* ``Obj1`` despite the usual order of
initialization being the opposite.

This attribute is only supported for C++ and Objective-C++ and is ignored in
other language modes. Currently, this attribute is not implemented on z/OS.
  }];
}

def InitSegDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The attribute applied by ``pragma init_seg()`` controls the section into
which global initialization function pointers are emitted. It is only
available with ``-fms-extensions``. Typically, this function pointer is
emitted into ``.CRT$XCU`` on Windows. The user can change the order of
initialization by using a different section name with the same
``.CRT$XC`` prefix and a suffix that sorts lexicographically before or
after the standard ``.CRT$XCU`` sections. See the init_seg_
documentation on MSDN for more information.

.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx
  }];
}

def TLSModelDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``tls_model`` attribute allows you to specify which thread-local storage
model to use. It accepts the following strings:

* global-dynamic
* local-dynamic
* initial-exec
* local-exec

TLS models are mutually exclusive.
  }];
}

def DLLExportDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``__declspec(dllexport)`` attribute declares a variable, function, or
Objective-C interface to be exported from the module. It is available under the
``-fdeclspec`` flag for compatibility with various compilers. The primary use
is for COFF object files which explicitly specify what interfaces are available
for external use. See the dllexport_ documentation on MSDN for more
information.

.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
  }];
}

def DLLImportDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``__declspec(dllimport)`` attribute declares a variable, function, or
Objective-C interface to be imported from an external module. It is available
under the ``-fdeclspec`` flag for compatibility with various compilers. The
primary use is for COFF object files which explicitly specify what interfaces
are imported from external modules. See the dllimport_ documentation on MSDN
for more information.

.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
  }];
}

def ThreadDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``__declspec(thread)`` attribute declares a variable with thread local
storage. It is available under the ``-fms-extensions`` flag for MSVC
compatibility. See the documentation for `__declspec(thread)`_ on MSDN.

.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx

In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
GNU ``__thread`` keyword. The variable must not have a destructor and must have
a constant initializer, if any. The attribute only applies to variables
declared with static storage duration, such as globals, class static data
members, and static locals.
  }];
}

def NoEscapeDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
``noescape`` placed on a function parameter of a pointer type is used to inform
the compiler that the pointer cannot escape: that is, no reference to the object
the pointer points to that is derived from the parameter value will survive
after the function returns. Users are responsible for making sure parameters
annotated with ``noescape`` do not actually escape. Calling ``free()`` on such
a parameter does not constitute an escape.

For example:

.. code-block:: c

  int *gp;

  void nonescapingFunc(__attribute__((noescape)) int *p) {
    *p += 100; // OK.
  }

  void escapingFunc(__attribute__((noescape)) int *p) {
    gp = p; // Not OK.
  }

Additionally, when the parameter is a `block pointer
<https://clang.llvm.org/docs/BlockLanguageSpec.html>`, the same restriction
applies to copies of the block. For example:

.. code-block:: c

  typedef void (^BlockTy)();
  BlockTy g0, g1;

  void nonescapingFunc(__attribute__((noescape)) BlockTy block) {
    block(); // OK.
  }

  void escapingFunc(__attribute__((noescape)) BlockTy block) {
    g0 = block; // Not OK.
    g1 = Block_copy(block); // Not OK either.
  }

  }];
}

def CarriesDependencyDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``carries_dependency`` attribute specifies dependency propagation into and
out of functions.

When specified on a function or Objective-C method, the ``carries_dependency``
attribute means that the return value carries a dependency out of the function,
so that the implementation need not constrain ordering upon return from that
function. Implementations of the function and its caller may choose to preserve
dependencies instead of emitting memory ordering instructions such as fences.

Note, this attribute does not change the meaning of the program, but may result
in generation of more efficient code.
  }];
}

def CPUSpecificCPUDispatchDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``cpu_specific`` and ``cpu_dispatch`` attributes are used to define and
resolve multiversioned functions. This form of multiversioning provides a
mechanism for declaring versions across translation units and manually
specifying the resolved function list. A specified CPU defines a set of minimum
features that are required for the function to be called. The result of this is
that future processors execute the most restrictive version of the function the
new processor can execute.

Function versions are defined with ``cpu_specific``, which takes one or more CPU
names as a parameter. For example:

.. code-block:: c

  // Declares and defines the ivybridge version of single_cpu.
  __attribute__((cpu_specific(ivybridge)))
  void single_cpu(void){}

  // Declares and defines the atom version of single_cpu.
  __attribute__((cpu_specific(atom)))
  void single_cpu(void){}

  // Declares and defines both the ivybridge and atom version of multi_cpu.
  __attribute__((cpu_specific(ivybridge, atom)))
  void multi_cpu(void){}

A dispatching (or resolving) function can be declared anywhere in a project's
source code with ``cpu_dispatch``. This attribute takes one or more CPU names
as a parameter (like ``cpu_specific``). Functions marked with ``cpu_dispatch``
are not expected to be defined, only declared. If such a marked function has a
definition, any side effects of the function are ignored; trivial function
bodies are permissible for ICC compatibility.

.. code-block:: c

  // Creates a resolver for single_cpu above.
  __attribute__((cpu_dispatch(ivybridge, atom)))
  void single_cpu(void){}

  // Creates a resolver for multi_cpu, but adds a 3rd version defined in another
  // translation unit.
  __attribute__((cpu_dispatch(ivybridge, atom, sandybridge)))
  void multi_cpu(void){}

Note that it is possible to have a resolving function that dispatches based on
more or fewer options than are present in the program. Specifying fewer will
result in the omitted options not being considered during resolution. Specifying
a version for resolution that isn't defined in the program will result in a
linking failure.

It is also possible to specify a CPU name of ``generic`` which will be resolved
if the executing processor doesn't satisfy the features required in the CPU
name. The behavior of a program executing on a processor that doesn't satisfy
any option of a multiversioned function is undefined.
  }];
}

def SYCLKernelDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``sycl_kernel`` attribute specifies that a function template will be used
to outline device code and to generate an OpenCL kernel.
Here is a code example of the SYCL program, which demonstrates the compiler's
outlining job:

.. code-block:: c++

  int foo(int x) { return ++x; }

  using namespace cl::sycl;
  queue Q;
  buffer<int, 1> a(range<1>{1024});
  Q.submit([&](handler& cgh) {
    auto A = a.get_access<access::mode::write>(cgh);
    cgh.parallel_for<init_a>(range<1>{1024}, [=](id<1> index) {
      A[index] = index[0] + foo(42);
    });
  }

A C++ function object passed to the ``parallel_for`` is called a "SYCL kernel".
A SYCL kernel defines the entry point to the "device part" of the code. The
compiler will emit all symbols accessible from a "kernel". In this code
example, the compiler will emit "foo" function. More details about the
compilation of functions for the device part can be found in the SYCL 1.2.1
specification Section 6.4.
To show to the compiler entry point to the "device part" of the code, the SYCL
runtime can use the ``sycl_kernel`` attribute in the following way:

.. code-block:: c++

  namespace cl {
  namespace sycl {
  class handler {
    template <typename KernelName, typename KernelType/*, ...*/>
    __attribute__((sycl_kernel)) void sycl_kernel_function(KernelType KernelFuncObj) {
      // ...
      KernelFuncObj();
    }

    template <typename KernelName, typename KernelType, int Dims>
    void parallel_for(range<Dims> NumWorkItems, KernelType KernelFunc) {
  #ifdef __SYCL_DEVICE_ONLY__
      sycl_kernel_function<KernelName, KernelType, Dims>(KernelFunc);
  #else
      // Host implementation
  #endif
    }
  };
  } // namespace sycl
  } // namespace cl

The compiler will also generate an OpenCL kernel using the function marked with
the ``sycl_kernel`` attribute.
Here is the list of SYCL device compiler expectations with regard to the
function marked with the ``sycl_kernel`` attribute:

- The function must be a template with at least two type template parameters.
  The compiler generates an OpenCL kernel and uses the first template parameter
  as a unique name for the generated OpenCL kernel. The host application uses
  this unique name to invoke the OpenCL kernel generated for the SYCL kernel
  specialized by this name and second template parameter ``KernelType`` (which
  might be an unnamed function object type).
- The function must have at least one parameter. The first parameter is
  required to be a function object type (named or unnamed i.e. lambda). The
  compiler uses function object type fields to generate OpenCL kernel
  parameters.
- The function must return void. The compiler reuses the body of marked functions to
  generate the OpenCL kernel body, and the OpenCL kernel must return ``void``.

The SYCL kernel in the previous code sample meets these expectations.
  }];
}

def C11NoReturnDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
A function declared as ``_Noreturn`` shall not return to its caller. The
compiler will generate a diagnostic for a function declared as ``_Noreturn``
that appears to be capable of returning to its caller. Despite being a type
specifier, the ``_Noreturn`` attribute cannot be specified on a function
pointer type.
  }];
}

def CXX11NoReturnDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
A function declared as ``[[noreturn]]`` shall not return to its caller. The
compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
that appears to be capable of returning to its caller.
  }];
}

def NoMergeDocs : Documentation {
  let Category = DocCatStmt;
  let Content = [{
If a statement is marked ``nomerge`` and contains call expressions, those call
expressions inside the statement will not be merged during optimization. This 
attribute can be used to prevent the optimizer from obscuring the source
location of certain calls. For example, it will prevent tail merging otherwise
identical code sequences that raise an exception or terminate the program. Tail
merging normally reduces the precision of source location information, making
stack traces less useful for debugging. This attribute gives the user control
over the tradeoff between code size and debug information precision. 

``nomerge`` attribute can also be used as function attribute to prevent all 
calls to the specified function from merging. It has no effect on indirect 
calls.
  }];
}

def AssertCapabilityDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "assert_capability, assert_shared_capability";
  let Content = [{
Marks a function that dynamically tests whether a capability is held, and halts
the program if it is not held.
  }];
}

def AcquireCapabilityDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "acquire_capability, acquire_shared_capability";
  let Content = [{
Marks a function as acquiring a capability.
  }];
}

def TryAcquireCapabilityDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "try_acquire_capability, try_acquire_shared_capability";
  let Content = [{
Marks a function that attempts to acquire a capability. This function may fail to
actually acquire the capability; they accept a Boolean value determining
whether acquiring the capability means success (true), or failing to acquire
the capability means success (false).
  }];
}

def ReleaseCapabilityDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "release_capability, release_shared_capability";
  let Content = [{
Marks a function as releasing a capability.
  }];
}

def AssumeAlignedDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use ``__attribute__((assume_aligned(<alignment>[,<offset>]))`` on a function
declaration to specify that the return value of the function (which must be a
pointer type) has the specified offset, in bytes, from an address with the
specified alignment. The offset is taken to be zero if omitted.

.. code-block:: c++

  // The returned pointer value has 32-byte alignment.
  void *a() __attribute__((assume_aligned (32)));

  // The returned pointer value is 4 bytes greater than an address having
  // 32-byte alignment.
  void *b() __attribute__((assume_aligned (32, 4)));

Note that this attribute provides information to the compiler regarding a
condition that the code already ensures is true. It does not cause the compiler
to enforce the provided alignment assumption.
  }];
}

def AllocSizeDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``alloc_size`` attribute can be placed on functions that return pointers in
order to hint to the compiler how many bytes of memory will be available at the
returned pointer. ``alloc_size`` takes one or two arguments.

- ``alloc_size(N)`` implies that argument number N equals the number of
  available bytes at the returned pointer.
- ``alloc_size(N, M)`` implies that the product of argument number N and
  argument number M equals the number of available bytes at the returned
  pointer.

Argument numbers are 1-based.

An example of how to use ``alloc_size``

.. code-block:: c

  void *my_malloc(int a) __attribute__((alloc_size(1)));
  void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2)));

  int main() {
    void *const p = my_malloc(100);
    assert(__builtin_object_size(p, 0) == 100);
    void *const a = my_calloc(20, 5);
    assert(__builtin_object_size(a, 0) == 100);
  }

.. Note:: This attribute works differently in clang than it does in GCC.
  Specifically, clang will only trace ``const`` pointers (as above); we give up
  on pointers that are not marked as ``const``. In the vast majority of cases,
  this is unimportant, because LLVM has support for the ``alloc_size``
  attribute. However, this may cause mildly unintuitive behavior when used with
  other attributes, such as ``enable_if``.
  }];
}

def CodeSegDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``__declspec(code_seg)`` attribute enables the placement of code into separate
named segments that can be paged or locked in memory individually. This attribute
is used to control the placement of instantiated templates and compiler-generated
code. See the documentation for `__declspec(code_seg)`_ on MSDN.

.. _`__declspec(code_seg)`: http://msdn.microsoft.com/en-us/library/dn636922.aspx
  }];
}

def AllocAlignDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use ``__attribute__((alloc_align(<alignment>))`` on a function
declaration to specify that the return value of the function (which must be a
pointer type) is at least as aligned as the value of the indicated parameter. The
parameter is given by its index in the list of formal parameters; the first
parameter has index 1 unless the function is a C++ non-static member function,
in which case the first parameter has index 2 to account for the implicit ``this``
parameter.

.. code-block:: c++

  // The returned pointer has the alignment specified by the first parameter.
  void *a(size_t align) __attribute__((alloc_align(1)));

  // The returned pointer has the alignment specified by the second parameter.
  void *b(void *v, size_t align) __attribute__((alloc_align(2)));

  // The returned pointer has the alignment specified by the second visible
  // parameter, however it must be adjusted for the implicit 'this' parameter.
  void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3)));

Note that this attribute merely informs the compiler that a function always
returns a sufficiently aligned pointer. It does not cause the compiler to
emit code to enforce that alignment. The behavior is undefined if the returned
pointer is not sufficiently aligned.
  }];
}

def EnableIfDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
.. Note:: Some features of this attribute are experimental. The meaning of
  multiple enable_if attributes on a single declaration is subject to change in
  a future version of clang. Also, the ABI is not standardized and the name
  mangling may change in future versions. To avoid that, use asm labels.

The ``enable_if`` attribute can be placed on function declarations to control
which overload is selected based on the values of the function's arguments.
When combined with the ``overloadable`` attribute, this feature is also
available in C.

.. code-block:: c++

  int isdigit(int c);
  int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));

  void foo(char c) {
    isdigit(c);
    isdigit(10);
    isdigit(-10);  // results in a compile-time error.
  }

The enable_if attribute takes two arguments, the first is an expression written
in terms of the function parameters, the second is a string explaining why this
overload candidate could not be selected to be displayed in diagnostics. The
expression is part of the function signature for the purposes of determining
whether it is a redeclaration (following the rules used when determining
whether a C++ template specialization is ODR-equivalent), but is not part of
the type.

The enable_if expression is evaluated as if it were the body of a
bool-returning constexpr function declared with the arguments of the function
it is being applied to, then called with the parameters at the call site. If the
result is false or could not be determined through constant expression
evaluation, then this overload will not be chosen and the provided string may
be used in a diagnostic if the compile fails as a result.

Because the enable_if expression is an unevaluated context, there are no global
state changes, nor the ability to pass information from the enable_if
expression to the function body. For example, suppose we want calls to
strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
strbuf) only if the size of strbuf can be determined:

.. code-block:: c++

  __attribute__((always_inline))
  static inline size_t strnlen(const char *s, size_t maxlen)
    __attribute__((overloadable))
    __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
                             "chosen when the buffer size is known but 'maxlen' is not")))
  {
    return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
  }

Multiple enable_if attributes may be applied to a single declaration. In this
case, the enable_if expressions are evaluated from left to right in the
following manner. First, the candidates whose enable_if expressions evaluate to
false or cannot be evaluated are discarded. If the remaining candidates do not
share ODR-equivalent enable_if expressions, the overload resolution is
ambiguous. Otherwise, enable_if overload resolution continues with the next
enable_if attribute on the candidates that have not been discarded and have
remaining enable_if attributes. In this way, we pick the most specific
overload out of a number of viable overloads using enable_if.

.. code-block:: c++

  void f() __attribute__((enable_if(true, "")));  // #1
  void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, "")));  // #2

  void g(int i, int j) __attribute__((enable_if(i, "")));  // #1
  void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true)));  // #2

In this example, a call to f() is always resolved to #2, as the first enable_if
expression is ODR-equivalent for both declarations, but #1 does not have another
enable_if expression to continue evaluating, so the next round of evaluation has
only a single candidate. In a call to g(1, 1), the call is ambiguous even though
#2 has more enable_if attributes, because the first enable_if expressions are
not ODR-equivalent.

Query for this feature with ``__has_attribute(enable_if)``.

Note that functions with one or more ``enable_if`` attributes may not have
their address taken, unless all of the conditions specified by said
``enable_if`` are constants that evaluate to ``true``. For example:

.. code-block:: c

  const int TrueConstant = 1;
  const int FalseConstant = 0;
  int f(int a) __attribute__((enable_if(a > 0, "")));
  int g(int a) __attribute__((enable_if(a == 0 || a != 0, "")));
  int h(int a) __attribute__((enable_if(1, "")));
  int i(int a) __attribute__((enable_if(TrueConstant, "")));
  int j(int a) __attribute__((enable_if(FalseConstant, "")));

  void fn() {
    int (*ptr)(int);
    ptr = &f; // error: 'a > 0' is not always true
    ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant
    ptr = &h; // OK: 1 is a truthy constant
    ptr = &i; // OK: 'TrueConstant' is a truthy constant
    ptr = &j; // error: 'FalseConstant' is a constant, but not truthy
  }

Because ``enable_if`` evaluation happens during overload resolution,
``enable_if`` may give unintuitive results when used with templates, depending
on when overloads are resolved. In the example below, clang will emit a
diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``:

.. code-block:: c++

  double foo(int i) __attribute__((enable_if(i > 0, "")));
  void *foo(int i) __attribute__((enable_if(i <= 0, "")));
  template <int I>
  auto bar() { return foo(I); }

  template <typename T>
  auto baz() { return foo(T::number); }

  struct WithNumber { constexpr static int number = 1; };
  void callThem() {
    bar<sizeof(WithNumber)>();
    baz<WithNumber>();
  }

This is because, in ``bar``, ``foo`` is resolved prior to template
instantiation, so the value for ``I`` isn't known (thus, both ``enable_if``
conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during
template instantiation, so the value for ``T::number`` is known.
  }];
}

def DiagnoseIfDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``diagnose_if`` attribute can be placed on function declarations to emit
warnings or errors at compile-time if calls to the attributed function meet
certain user-defined criteria. For example:

.. code-block:: c

  int abs(int a)
    __attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
  int must_abs(int a)
    __attribute__((diagnose_if(a >= 0, "Redundant abs call", "error")));

  int val = abs(1); // warning: Redundant abs call
  int val2 = must_abs(1); // error: Redundant abs call
  int val3 = abs(val);
  int val4 = must_abs(val); // Because run-time checks are not emitted for
                            // diagnose_if attributes, this executes without
                            // issue.


``diagnose_if`` is closely related to ``enable_if``, with a few key differences:

* Overload resolution is not aware of ``diagnose_if`` attributes: they're
  considered only after we select the best candidate from a given candidate set.
* Function declarations that differ only in their ``diagnose_if`` attributes are
  considered to be redeclarations of the same function (not overloads).
* If the condition provided to ``diagnose_if`` cannot be evaluated, no
  diagnostic will be emitted.

Otherwise, ``diagnose_if`` is essentially the logical negation of ``enable_if``.

As a result of bullet number two, ``diagnose_if`` attributes will stack on the
same function. For example:

.. code-block:: c

  int foo() __attribute__((diagnose_if(1, "diag1", "warning")));
  int foo() __attribute__((diagnose_if(1, "diag2", "warning")));

  int bar = foo(); // warning: diag1
                   // warning: diag2
  int (*fooptr)(void) = foo; // warning: diag1
                             // warning: diag2

  constexpr int supportsAPILevel(int N) { return N < 5; }
  int baz(int a)
    __attribute__((diagnose_if(!supportsAPILevel(10),
                               "Upgrade to API level 10 to use baz", "error")));
  int baz(int a)
    __attribute__((diagnose_if(!a, "0 is not recommended.", "warning")));

  int (*bazptr)(int) = baz; // error: Upgrade to API level 10 to use baz
  int v = baz(0); // error: Upgrade to API level 10 to use baz

Query for this feature with ``__has_attribute(diagnose_if)``.
  }];
}

def PassObjectSizeDocs : Documentation {
  let Category = DocCatVariable; // Technically it's a parameter doc, but eh.
  let Heading = "pass_object_size, pass_dynamic_object_size";
  let Content = [{
.. Note:: The mangling of functions with parameters that are annotated with
  ``pass_object_size`` is subject to change. You can get around this by
  using ``__asm__("foo")`` to explicitly name your functions, thus preserving
  your ABI; also, non-overloadable C functions with ``pass_object_size`` are
  not mangled.

The ``pass_object_size(Type)`` attribute can be placed on function parameters to
instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite
of said function, and implicitly pass the result of this call in as an invisible
argument of type ``size_t`` directly after the parameter annotated with
``pass_object_size``. Clang will also replace any calls to
``__builtin_object_size(param, Type)`` in the function by said implicit
parameter.

Example usage:

.. code-block:: c

  int bzero1(char *const p __attribute__((pass_object_size(0))))
      __attribute__((noinline)) {
    int i = 0;
    for (/**/; i < (int)__builtin_object_size(p, 0); ++i) {
      p[i] = 0;
    }
    return i;
  }

  int main() {
    char chars[100];
    int n = bzero1(&chars[0]);
    assert(n == sizeof(chars));
    return 0;
  }

If successfully evaluating ``__builtin_object_size(param, Type)`` at the
callsite is not possible, then the "failed" value is passed in. So, using the
definition of ``bzero1`` from above, the following code would exit cleanly:

.. code-block:: c

  int main2(int argc, char *argv[]) {
    int n = bzero1(argv);
    assert(n == -1);
    return 0;
  }

``pass_object_size`` plays a part in overload resolution. If two overload
candidates are otherwise equally good, then the overload with one or more
parameters with ``pass_object_size`` is preferred. This implies that the choice
between two identical overloads both with ``pass_object_size`` on one or more
parameters will always be ambiguous; for this reason, having two such overloads
is illegal. For example:

.. code-block:: c++

  #define PS(N) __attribute__((pass_object_size(N)))
  // OK
  void Foo(char *a, char *b); // Overload A
  // OK -- overload A has no parameters with pass_object_size.
  void Foo(char *a PS(0), char *b PS(0)); // Overload B
  // Error -- Same signature (sans pass_object_size) as overload B, and both
  // overloads have one or more parameters with the pass_object_size attribute.
  void Foo(void *a PS(0), void *b);

  // OK
  void Bar(void *a PS(0)); // Overload C
  // OK
  void Bar(char *c PS(1)); // Overload D

  void main() {
    char known[10], *unknown;
    Foo(unknown, unknown); // Calls overload B
    Foo(known, unknown); // Calls overload B
    Foo(unknown, known); // Calls overload B
    Foo(known, known); // Calls overload B

    Bar(known); // Calls overload D
    Bar(unknown); // Calls overload D
  }

Currently, ``pass_object_size`` is a bit restricted in terms of its usage:

* Only one use of ``pass_object_size`` is allowed per parameter.

* It is an error to take the address of a function with ``pass_object_size`` on
  any of its parameters. If you wish to do this, you can create an overload
  without ``pass_object_size`` on any parameters.

* It is an error to apply the ``pass_object_size`` attribute to parameters that
  are not pointers. Additionally, any parameter that ``pass_object_size`` is
  applied to must be marked ``const`` at its function's definition.

Clang also supports the ``pass_dynamic_object_size`` attribute, which behaves
identically to ``pass_object_size``, but evaluates a call to
``__builtin_dynamic_object_size`` at the callee instead of
``__builtin_object_size``. ``__builtin_dynamic_object_size`` provides some extra
runtime checks when the object size can't be determined at compile-time. You can
read more about ``__builtin_dynamic_object_size`` `here
<https://clang.llvm.org/docs/LanguageExtensions.html#evaluating-object-size-dynamically>`_.

  }];
}

def OverloadableDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang provides support for C++ function overloading in C. Function overloading
in C is introduced using the ``overloadable`` attribute. For example, one
might provide several overloaded versions of a ``tgsin`` function that invokes
the appropriate standard function computing the sine of a value with ``float``,
``double``, or ``long double`` precision:

.. code-block:: c

  #include <math.h>
  float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
  double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
  long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }

Given these declarations, one can call ``tgsin`` with a ``float`` value to
receive a ``float`` result, with a ``double`` to receive a ``double`` result,
etc. Function overloading in C follows the rules of C++ function overloading
to pick the best overload given the call arguments, with a few C-specific
semantics:

* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
  floating-point promotion (per C99) rather than as a floating-point conversion
  (as in C++).

* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
  considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
  compatible types.

* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
  and ``U`` are compatible types. This conversion is given "conversion" rank.

* If no viable candidates are otherwise available, we allow a conversion from a
  pointer of type ``T*`` to a pointer of type ``U*``, where ``T`` and ``U`` are
  incompatible. This conversion is ranked below all other types of conversions.
  Please note: ``U`` lacking qualifiers that are present on ``T`` is sufficient
  for ``T`` and ``U`` to be incompatible.

The declaration of ``overloadable`` functions is restricted to function
declarations and definitions. If a function is marked with the ``overloadable``
attribute, then all declarations and definitions of functions with that name,
except for at most one (see the note below about unmarked overloads), must have
the ``overloadable`` attribute. In addition, redeclarations of a function with
the ``overloadable`` attribute must have the ``overloadable`` attribute, and
redeclarations of a function without the ``overloadable`` attribute must *not*
have the ``overloadable`` attribute. e.g.,

.. code-block:: c

  int f(int) __attribute__((overloadable));
  float f(float); // error: declaration of "f" must have the "overloadable" attribute
  int f(int); // error: redeclaration of "f" must have the "overloadable" attribute

  int g(int) __attribute__((overloadable));
  int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute

  int h(int);
  int h(int) __attribute__((overloadable)); // error: declaration of "h" must not
                                            // have the "overloadable" attribute

Functions marked ``overloadable`` must have prototypes. Therefore, the
following code is ill-formed:

.. code-block:: c

  int h() __attribute__((overloadable)); // error: h does not have a prototype

However, ``overloadable`` functions are allowed to use a ellipsis even if there
are no named parameters (as is permitted in C++). This feature is particularly
useful when combined with the ``unavailable`` attribute:

.. code-block:: c++

  void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error

Functions declared with the ``overloadable`` attribute have their names mangled
according to the same rules as C++ function names. For example, the three
``tgsin`` functions in our motivating example get the mangled names
``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two
caveats to this use of name mangling:

* Future versions of Clang may change the name mangling of functions overloaded
  in C, so you should not depend on an specific mangling. To be completely
  safe, we strongly urge the use of ``static inline`` with ``overloadable``
  functions.

* The ``overloadable`` attribute has almost no meaning when used in C++,
  because names will already be mangled and functions are already overloadable.
  However, when an ``overloadable`` function occurs within an ``extern "C"``
  linkage specification, it's name *will* be mangled in the same way as it
  would in C.

For the purpose of backwards compatibility, at most one function with the same
name as other ``overloadable`` functions may omit the ``overloadable``
attribute. In this case, the function without the ``overloadable`` attribute
will not have its name mangled.

For example:

.. code-block:: c

  // Notes with mangled names assume Itanium mangling.
  int f(int);
  int f(double) __attribute__((overloadable));
  void foo() {
    f(5); // Emits a call to f (not _Z1fi, as it would with an overload that
          // was marked with overloadable).
    f(1.0); // Emits a call to _Z1fd.
  }

Support for unmarked overloads is not present in some versions of clang. You may
query for it using ``__has_extension(overloadable_unmarked)``.

Query for this attribute with ``__has_attribute(overloadable)``.
  }];
}

def ObjCMethodFamilyDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Many methods in Objective-C have conventional meanings determined by their
selectors. It is sometimes useful to be able to mark a method as having a
particular conventional meaning despite not having the right selector, or as
not having the conventional meaning that its selector would suggest. For these
use cases, we provide an attribute to specifically describe the "method family"
that a method belongs to.

**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This
attribute can only be placed at the end of a method declaration:

.. code-block:: objc

  - (NSString *)initMyStringValue __attribute__((objc_method_family(none)));

Users who do not wish to change the conventional meaning of a method, and who
merely want to document its non-standard retain and release semantics, should
use the retaining behavior attributes (``ns_returns_retained``,
``ns_returns_not_retained``, etc).

Query for this feature with ``__has_attribute(objc_method_family)``.
  }];
}

def RetainBehaviorDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The behavior of a function with respect to reference counting for Foundation
(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming
convention (e.g. functions starting with "get" are assumed to return at
``+0``).

It can be overridden using a family of the following attributes. In
Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to
a function communicates that the object is returned at ``+1``, and the caller
is responsible for freeing it.
Similarly, the annotation ``__attribute__((ns_returns_not_retained))``
specifies that the object is returned at ``+0`` and the ownership remains with
the callee.
The annotation ``__attribute__((ns_consumes_self))`` specifies that
the Objective-C method call consumes the reference to ``self``, e.g. by
attaching it to a supplied parameter.
Additionally, parameters can have an annotation
``__attribute__((ns_consumed))``, which specifies that passing an owned object
as that parameter effectively transfers the ownership, and the caller is no
longer responsible for it.
These attributes affect code generation when interacting with ARC code, and
they are used by the Clang Static Analyzer.

In C programs using CoreFoundation, a similar set of attributes:
``__attribute__((cf_returns_not_retained))``,
``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))``
have the same respective semantics when applied to CoreFoundation objects.
These attributes affect code generation when interacting with ARC code, and
they are used by the Clang Static Analyzer.

Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject),
the same attribute family is present:
``__attribute__((os_returns_not_retained))``,
``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``,
with the same respective semantics.
Similar to ``__attribute__((ns_consumes_self))``,
``__attribute__((os_consumes_this))`` specifies that the method call consumes
the reference to "this" (e.g., when attaching it to a different object supplied
as a parameter).
Out parameters (parameters the function is meant to write into,
either via pointers-to-pointers or references-to-pointers)
may be annotated with ``__attribute__((os_returns_retained))``
or ``__attribute__((os_returns_not_retained))`` which specifies that the object
written into the out parameter should (or respectively should not) be released
after use.
Since often out parameters may or may not be written depending on the exit
code of the function,
annotations ``__attribute__((os_returns_retained_on_zero))``
and ``__attribute__((os_returns_retained_on_non_zero))`` specify that
an out parameter at ``+1`` is written if and only if the function returns a zero
(respectively non-zero) error code.
Observe that return-code-dependent out parameter annotations are only
available for retained out parameters, as non-retained object do not have to be
released by the callee.
These attributes are only used by the Clang Static Analyzer.

The family of attributes ``X_returns_X_retained`` can be added to functions,
C++ methods, and Objective-C methods and properties.
Attributes ``X_consumed`` can be added to parameters of methods, functions,
and Objective-C methods.
  }];
}

def NoDebugDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``nodebug`` attribute allows you to suppress debugging information for a
function or method, for a variable that is not a parameter or a non-static
data member, or for a typedef or using declaration.
  }];
}

def StandaloneDebugDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``standalone_debug`` attribute causes debug info to be emitted for a record
type regardless of the debug info optimizations that are enabled with
-fno-standalone-debug. This attribute only has an effect when debug info
optimizations are enabled (e.g. with -fno-standalone-debug), and is C++-only.
  }];
}

def NoDuplicateDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``noduplicate`` attribute can be placed on function declarations to control
whether function calls to this function can be duplicated or not as a result of
optimizations. This is required for the implementation of functions with
certain special requirements, like the OpenCL "barrier" function, that might
need to be run concurrently by all the threads that are executing in lockstep
on the hardware. For example this attribute applied on the function
"nodupfunc" in the code below avoids that:

.. code-block:: c

  void nodupfunc() __attribute__((noduplicate));
  // Setting it as a C++11 attribute is also valid
  // void nodupfunc() [[clang::noduplicate]];
  void foo();
  void bar();

  nodupfunc();
  if (a > n) {
    foo();
  } else {
    bar();
  }

gets possibly modified by some optimizations into code similar to this:

.. code-block:: c

  if (a > n) {
    nodupfunc();
    foo();
  } else {
    nodupfunc();
    bar();
  }

where the call to "nodupfunc" is duplicated and sunk into the two branches
of the condition.
  }];
}

def ConvergentDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``convergent`` attribute can be placed on a function declaration. It is
translated into the LLVM ``convergent`` attribute, which indicates that the call
instructions of a function with this attribute cannot be made control-dependent
on any additional values.

In languages designed for SPMD/SIMT programming model, e.g. OpenCL or CUDA,
the call instructions of a function with this attribute must be executed by
all work items or threads in a work group or sub group.

This attribute is different from ``noduplicate`` because it allows duplicating
function calls if it can be proved that the duplicated function calls are
not made control-dependent on any additional values, e.g., unrolling a loop
executed by all work items.

Sample usage:

.. code-block:: c

  void convfunc(void) __attribute__((convergent));
  // Setting it as a C++11 attribute is also valid in a C++ program.
  // void convfunc(void) [[clang::convergent]];

  }];
}

def NoSplitStackDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``no_split_stack`` attribute disables the emission of the split stack
preamble for a particular function. It has no effect if ``-fsplit-stack``
is not specified.
  }];
}

def NoUniqueAddressDocs : Documentation {
  let Category = DocCatField;
  let Content = [{
The ``no_unique_address`` attribute allows tail padding in a non-static data
member to overlap other members of the enclosing class (and in the special
case when the type is empty, permits it to fully overlap other members).
The field is laid out as if a base class were encountered at the corresponding
point within the class (except that it does not share a vptr with the enclosing
object).

Example usage:

.. code-block:: c++

  template<typename T, typename Alloc> struct my_vector {
    T *p;
    [[no_unique_address]] Alloc alloc;
    // ...
  };
  static_assert(sizeof(my_vector<int, std::allocator<int>>) == sizeof(int*));

``[[no_unique_address]]`` is a standard C++20 attribute. Clang supports its use
in C++11 onwards.
  }];
}

def ObjCRequiresSuperDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Some Objective-C classes allow a subclass to override a particular method in a
parent class but expect that the overriding method also calls the overridden
method in the parent class. For these cases, we provide an attribute to
designate that a method requires a "call to ``super``" in the overriding
method in the subclass.

**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only
be placed at the end of a method declaration:

.. code-block:: objc

  - (void)foo __attribute__((objc_requires_super));

This attribute can only be applied the method declarations within a class, and
not a protocol. Currently this attribute does not enforce any placement of
where the call occurs in the overriding method (such as in the case of
``-dealloc`` where the call must appear at the end). It checks only that it
exists.

Note that on both OS X and iOS that the Foundation framework provides a
convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
attribute:

.. code-block:: objc

  - (void)foo NS_REQUIRES_SUPER;

This macro is conditionally defined depending on the compiler's support for
this attribute. If the compiler does not support the attribute the macro
expands to nothing.

Operationally, when a method has this annotation the compiler will warn if the
implementation of an override in a subclass does not call super. For example:

.. code-block:: objc

   warning: method possibly missing a [super AnnotMeth] call
   - (void) AnnotMeth{};
                      ^
  }];
}

def ObjCRuntimeNameDocs : Documentation {
    let Category = DocCatDecl;
    let Content = [{
By default, the Objective-C interface or protocol identifier is used
in the metadata name for that object. The ``objc_runtime_name``
attribute allows annotated interfaces or protocols to use the
specified string argument in the object's metadata name instead of the
default name.

**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute
can only be placed before an @protocol or @interface declaration:

.. code-block:: objc

  __attribute__((objc_runtime_name("MyLocalName")))
  @interface Message
  @end

    }];
}

def ObjCRuntimeVisibleDocs : Documentation {
    let Category = DocCatDecl;
    let Content = [{
This attribute specifies that the Objective-C class to which it applies is
visible to the Objective-C runtime but not to the linker. Classes annotated
with this attribute cannot be subclassed and cannot have categories defined for
them.
    }];
}

def ObjCClassStubDocs : Documentation {
    let Category = DocCatType;
    let Content = [{
This attribute specifies that the Objective-C class to which it applies is
instantiated at runtime.

Unlike ``__attribute__((objc_runtime_visible))``, a class having this attribute
still has a "class stub" that is visible to the linker. This allows categories
to be defined. Static message sends with the class as a receiver use a special
access pattern to ensure the class is lazily instantiated from the class stub.

Classes annotated with this attribute cannot be subclassed and cannot have
implementations defined for them. This attribute is intended for use in
Swift-generated headers for classes defined in Swift.

Adding or removing this attribute to a class is an ABI-breaking change.
    }];
}

def ObjCBoxableDocs : Documentation {
    let Category = DocCatDecl;
    let Content = [{
Structs and unions marked with the ``objc_boxable`` attribute can be used
with the Objective-C boxed expression syntax, ``@(...)``.

**Usage**: ``__attribute__((objc_boxable))``. This attribute
can only be placed on a declaration of a trivially-copyable struct or union:

.. code-block:: objc

  struct __attribute__((objc_boxable)) some_struct {
    int i;
  };
  union __attribute__((objc_boxable)) some_union {
    int i;
    float f;
  };
  typedef struct __attribute__((objc_boxable)) _some_struct some_struct;

  // ...

  some_struct ss;
  NSValue *boxed = @(ss);

    }];
}

def AvailabilityDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``availability`` attribute can be placed on declarations to describe the
lifecycle of that declaration relative to operating system versions. Consider
the function declaration for a hypothetical function ``f``:

.. code-block:: c++

  void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7)));

The availability attribute states that ``f`` was introduced in macOS 10.4,
deprecated in macOS 10.6, and obsoleted in macOS 10.7. This information
is used by Clang to determine when it is safe to use ``f``: for example, if
Clang is instructed to compile code for macOS 10.5, a call to ``f()``
succeeds. If Clang is instructed to compile code for macOS 10.6, the call
succeeds but Clang emits a warning specifying that the function is deprecated.
Finally, if Clang is instructed to compile code for macOS 10.7, the call
fails because ``f()`` is no longer available.

The availability attribute is a comma-separated list starting with the
platform name and then including clauses specifying important milestones in the
declaration's lifetime (in any order) along with additional information. Those
clauses can be:

introduced=\ *version*
  The first version in which this declaration was introduced.

deprecated=\ *version*
  The first version in which this declaration was deprecated, meaning that
  users should migrate away from this API.

obsoleted=\ *version*
  The first version in which this declaration was obsoleted, meaning that it
  was removed completely and can no longer be used.

unavailable
  This declaration is never available on this platform.

message=\ *string-literal*
  Additional message text that Clang will provide when emitting a warning or
  error about use of a deprecated or obsoleted declaration. Useful to direct
  users to replacement APIs.

replacement=\ *string-literal*
  Additional message text that Clang will use to provide Fix-It when emitting
  a warning about use of a deprecated declaration. The Fix-It will replace
  the deprecated declaration with the new declaration specified.

Multiple availability attributes can be placed on a declaration, which may
correspond to different platforms. For most platforms, the availability
attribute with the platform corresponding to the target platform will be used;
any others will be ignored. However, the availability for ``watchOS`` and
``tvOS`` can be implicitly inferred from an ``iOS`` availability attribute.
Any explicit availability attributes for those platforms are still preferred over
the implicitly inferred availability attributes. If no availability attribute
specifies availability for the current target platform, the availability
attributes are ignored. Supported platforms are:

``ios``
  Apple's iOS operating system. The minimum deployment target is specified by
  the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*``
  command-line arguments.

``macos``
  Apple's macOS operating system. The minimum deployment target is
  specified by the ``-mmacosx-version-min=*version*`` command-line argument.
  ``macosx`` is supported for backward-compatibility reasons, but it is
  deprecated.

``tvos``
  Apple's tvOS operating system. The minimum deployment target is specified by
  the ``-mtvos-version-min=*version*`` command-line argument.

``watchos``
  Apple's watchOS operating system. The minimum deployment target is specified by
  the ``-mwatchos-version-min=*version*`` command-line argument.

A declaration can typically be used even when deploying back to a platform
version prior to when the declaration was introduced. When this happens, the
declaration is `weakly linked
<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
as if the ``weak_import`` attribute were added to the declaration. A
weakly-linked declaration may or may not be present a run-time, and a program
can determine whether the declaration is present by checking whether the
address of that declaration is non-NULL.

The flag ``strict`` disallows using API when deploying back to a
platform version prior to when the declaration was introduced. An
attempt to use such API before its introduction causes a hard error.
Weakly-linking is almost always a better API choice, since it allows
users to query availability at runtime.

If there are multiple declarations of the same entity, the availability
attributes must either match on a per-platform basis or later
declarations must not have availability attributes for that
platform. For example:

.. code-block:: c

  void g(void) __attribute__((availability(macos,introduced=10.4)));
  void g(void) __attribute__((availability(macos,introduced=10.4))); // okay, matches
  void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform
  void g(void); // okay, inherits both macos and ios availability from above.
  void g(void) __attribute__((availability(macos,introduced=10.5))); // error: mismatch

When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,:

.. code-block:: objc

  @interface A
  - (id)method __attribute__((availability(macos,introduced=10.4)));
  - (id)method2 __attribute__((availability(macos,introduced=10.4)));
  @end

  @interface B : A
  - (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later
  - (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4
  @end

Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from
``<os/availability.h>`` can simplify the spelling:

.. code-block:: objc

  @interface A
  - (id)method API_AVAILABLE(macos(10.11)));
  - (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0));
  @end

Availability attributes can also be applied using a ``#pragma clang attribute``.
Any explicit availability attribute whose platform corresponds to the target
platform is applied to a declaration regardless of the availability attributes
specified in the pragma. For example, in the code below,
``hasExplicitAvailabilityAttribute`` will use the ``macOS`` availability
attribute that is specified with the declaration, whereas
``getsThePragmaAvailabilityAttribute`` will use the ``macOS`` availability
attribute that is applied by the pragma.

.. code-block:: c

  #pragma clang attribute push (__attribute__((availability(macOS, introduced=10.12))), apply_to=function)
  void getsThePragmaAvailabilityAttribute(void);
  void hasExplicitAvailabilityAttribute(void) __attribute__((availability(macos,introduced=10.4)));
  #pragma clang attribute pop

For platforms like ``watchOS`` and ``tvOS``, whose availability attributes can
be implicitly inferred from an ``iOS`` availability attribute, the logic is
slightly more complex. The explicit and the pragma-applied availability
attributes whose platform corresponds to the target platform are applied as
described in the previous paragraph. However, the implicitly inferred attributes
are applied to a declaration only when there is no explicit or pragma-applied
availability attribute whose platform corresponds to the target platform. For
example, the function below will receive the ``tvOS`` availability from the
pragma rather than using the inferred ``iOS`` availability from the declaration:

.. code-block:: c

  #pragma clang attribute push (__attribute__((availability(tvOS, introduced=12.0))), apply_to=function)
  void getsThePragmaTVOSAvailabilityAttribute(void) __attribute__((availability(iOS,introduced=11.0)));
  #pragma clang attribute pop

The compiler is also able to apply implicitly inferred attributes from a pragma
as well. For example, when targeting ``tvOS``, the function below will receive
a ``tvOS`` availability attribute that is implicitly inferred from the ``iOS``
availability attribute applied by the pragma:

.. code-block:: c

  #pragma clang attribute push (__attribute__((availability(iOS, introduced=12.0))), apply_to=function)
  void infersTVOSAvailabilityFromPragma(void);
  #pragma clang attribute pop

The implicit attributes that are inferred from explicitly specified attributes
whose platform corresponds to the target platform are applied to the declaration
even if there is an availability attribute that can be inferred from a pragma.
For example, the function below will receive the ``tvOS, introduced=11.0``
availability that is inferred from the attribute on the declaration rather than
inferring availability from the pragma:

.. code-block:: c

  #pragma clang attribute push (__attribute__((availability(iOS, unavailable))), apply_to=function)
  void infersTVOSAvailabilityFromAttributeNextToDeclaration(void)
    __attribute__((availability(iOS,introduced=11.0)));
  #pragma clang attribute pop

Also see the documentation for `@available
<http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-available>`_
  }];
}

def ExternalSourceSymbolDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``external_source_symbol`` attribute specifies that a declaration originates
from an external source and describes the nature of that source.

The fact that Clang is capable of recognizing declarations that were defined
externally can be used to provide better tooling support for mixed-language
projects or projects that rely on auto-generated code. For instance, an IDE that
uses Clang and that supports mixed-language projects can use this attribute to
provide a correct 'jump-to-definition' feature. For a concrete example,
consider a protocol that's defined in a Swift file:

.. code-block:: swift

  @objc public protocol SwiftProtocol {
    func method()
  }

This protocol can be used from Objective-C code by including a header file that
was generated by the Swift compiler. The declarations in that header can use
the ``external_source_symbol`` attribute to make Clang aware of the fact
that ``SwiftProtocol`` actually originates from a Swift module:

.. code-block:: objc

  __attribute__((external_source_symbol(language="Swift",defined_in="module")))
  @protocol SwiftProtocol
  @required
  - (void) method;
  @end

Consequently, when 'jump-to-definition' is performed at a location that
references ``SwiftProtocol``, the IDE can jump to the original definition in
the Swift source file rather than jumping to the Objective-C declaration in the
auto-generated header file.

The ``external_source_symbol`` attribute is a comma-separated list that includes
clauses that describe the origin and the nature of the particular declaration.
Those clauses can be:

language=\ *string-literal*
  The name of the source language in which this declaration was defined.

defined_in=\ *string-literal*
  The name of the source container in which the declaration was defined. The
  exact definition of source container is language-specific, e.g. Swift's
  source containers are modules, so ``defined_in`` should specify the Swift
  module name.

generated_declaration
  This declaration was automatically generated by some tool.

The clauses can be specified in any order. The clauses that are listed above are
all optional, but the attribute has to have at least one clause.
  }];
}

def ConstInitDocs : Documentation {
  let Category = DocCatVariable;
  let Heading = "require_constant_initialization, constinit (C++20)";
  let Content = [{
This attribute specifies that the variable to which it is attached is intended
to have a `constant initializer <http://en.cppreference.com/w/cpp/language/constant_initialization>`_
according to the rules of [basic.start.static]. The variable is required to
have static or thread storage duration. If the initialization of the variable
is not a constant initializer an error will be produced. This attribute may
only be used in C++; the ``constinit`` spelling is only accepted in C++20
onwards.

Note that in C++03 strict constant expression checking is not done. Instead
the attribute reports if Clang can emit the variable as a constant, even if it's
not technically a 'constant initializer'. This behavior is non-portable.

Static storage duration variables with constant initializers avoid hard-to-find
bugs caused by the indeterminate order of dynamic initialization. They can also
be safely used during dynamic initialization across translation units.

This attribute acts as a compile time assertion that the requirements
for constant initialization have been met. Since these requirements change
between dialects and have subtle pitfalls it's important to fail fast instead
of silently falling back on dynamic initialization.

The first use of the attribute on a variable must be part of, or precede, the
initializing declaration of the variable. C++20 requires the ``constinit``
spelling of the attribute to be present on the initializing declaration if it
is used anywhere. The other spellings can be specified on a forward declaration
and omitted on a later initializing declaration.

.. code-block:: c++

  // -std=c++14
  #define SAFE_STATIC [[clang::require_constant_initialization]]
  struct T {
    constexpr T(int) {}
    ~T(); // non-trivial
  };
  SAFE_STATIC T x = {42}; // Initialization OK. Doesn't check destructor.
  SAFE_STATIC T y = 42; // error: variable does not have a constant initializer
  // copy initialization is not a constant expression on a non-literal type.
  }];
}

def WarnMaybeUnusedDocs : Documentation {
  let Category = DocCatVariable;
  let Heading = "maybe_unused, unused";
  let Content = [{
When passing the ``-Wunused`` flag to Clang, entities that are unused by the
program may be diagnosed. The ``[[maybe_unused]]`` (or
``__attribute__((unused))``) attribute can be used to silence such diagnostics
when the entity cannot be removed. For instance, a local variable may exist
solely for use in an ``assert()`` statement, which makes the local variable
unused when ``NDEBUG`` is defined.

The attribute may be applied to the declaration of a class, a typedef, a
variable, a function or method, a function parameter, an enumeration, an
enumerator, a non-static data member, or a label.

.. code-block: c++
  #include <cassert>

  [[maybe_unused]] void f([[maybe_unused]] bool thing1,
                          [[maybe_unused]] bool thing2) {
    [[maybe_unused]] bool b = thing1 && thing2;
    assert(b);
  }
  }];
}

def WarnUnusedResultsDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "nodiscard, warn_unused_result";
  let Content  = [{
Clang supports the ability to diagnose when the results of a function call
expression are discarded under suspicious circumstances. A diagnostic is
generated when a function or its return type is marked with ``[[nodiscard]]``
(or ``__attribute__((warn_unused_result))``) and the function call appears as a
potentially-evaluated discarded-value expression that is not explicitly cast to
``void``.

A string literal may optionally be provided to the attribute, which will be
reproduced in any resulting diagnostics. Redeclarations using different forms
of the attribute (with or without the string literal or with different string
literal contents) are allowed. If there are redeclarations of the entity with
differing string literals, it is unspecified which one will be used by Clang
in any resulting diagnostics.

.. code-block: c++
  struct [[nodiscard]] error_info { /*...*/ };
  error_info enable_missile_safety_mode();

  void launch_missiles();
  void test_missiles() {
    enable_missile_safety_mode(); // diagnoses
    launch_missiles();
  }
  error_info &foo();
  void f() { foo(); } // Does not diagnose, error_info is a reference.

Additionally, discarded temporaries resulting from a call to a constructor
marked with ``[[nodiscard]]`` or a constructor of a type marked
``[[nodiscard]]`` will also diagnose. This also applies to type conversions that
use the annotated ``[[nodiscard]]`` constructor or result in an annotated type.

.. code-block: c++
  struct [[nodiscard]] marked_type {/*..*/ };
  struct marked_ctor {
    [[nodiscard]] marked_ctor();
    marked_ctor(int);
  };

  struct S {
    operator marked_type() const;
    [[nodiscard]] operator int() const;
  };

  void usages() {
    marked_type(); // diagnoses.
    marked_ctor(); // diagnoses.
    marked_ctor(3); // Does not diagnose, int constructor isn't marked nodiscard.

    S s;
    static_cast<marked_type>(s); // diagnoses
    (int)s; // diagnoses
  }
  }];
}

def FallthroughDocs : Documentation {
  let Category = DocCatStmt;
  let Heading = "fallthrough";
  let Content = [{
The ``fallthrough`` (or ``clang::fallthrough``) attribute is used
to annotate intentional fall-through
between switch labels. It can only be applied to a null statement placed at a
point of execution between any statement and the next switch label. It is
common to mark these places with a specific comment, but this attribute is
meant to replace comments with a more strict annotation, which can be checked
by the compiler. This attribute doesn't change semantics of the code and can
be used wherever an intended fall-through occurs. It is designed to mimic
control-flow statements like ``break;``, so it can be placed in most places
where ``break;`` can, but only if there are no statements on the execution path
between it and the next switch label.

By default, Clang does not warn on unannotated fallthrough from one ``switch``
case to another. Diagnostics on fallthrough without a corresponding annotation
can be enabled with the ``-Wimplicit-fallthrough`` argument.

Here is an example:

.. code-block:: c++

  // compile with -Wimplicit-fallthrough
  switch (n) {
  case 22:
  case 33:  // no warning: no statements between case labels
    f();
  case 44:  // warning: unannotated fall-through
    g();
    [[clang::fallthrough]];
  case 55:  // no warning
    if (x) {
      h();
      break;
    }
    else {
      i();
      [[clang::fallthrough]];
    }
  case 66:  // no warning
    p();
    [[clang::fallthrough]]; // warning: fallthrough annotation does not
                            //          directly precede case label
    q();
  case 77:  // warning: unannotated fall-through
    r();
  }
  }];
}

def LikelihoodDocs : Documentation {
  let Category = DocCatStmt;
  let Heading = "likely and unlikely";
  let Content = [{
The ``likely`` and ``unlikely`` attributes are used as compiler hints.
The attributes are used to aid the compiler to determine which branch is
likely or unlikely to be taken. This is done by marking the branch substatement
with one of the two attributes.

It isn't allowed to annotate a single statement with both ``likely`` and
``unlikely``. Annotating the ``true`` and ``false`` branch of an ``if``
statement with the same likelihood attribute will result in a diagnostic and
the attributes are ignored on both branches.

In a ``switch`` statement it's allowed to annotate multiple ``case`` labels
or the ``default`` label with the same likelihood attribute. This makes
* all labels without an attribute have a neutral likelihood,
* all labels marked ``[[likely]]`` have an equally positive likelihood, and
* all labels marked ``[[unlikely]]`` have an equally negative likelihood.
The neutral likelihood is the more likely of path execution than the negative
likelihood. The positive likelihood is the more likely of path of execution
than the neutral likelihood.

These attributes have no effect on the generated code when using
PGO (Profile-Guided Optimization) or at optimization level 0.

In Clang, the attributes will be ignored if they're not placed on
* the ``case`` or ``default`` label of a ``switch`` statement,
* or on the substatement of an ``if`` or ``else`` statement,
* or on the substatement of an ``for`` or ``while`` statement.
The C++ Standard recommends to honor them on every statement in the
path of execution, but that can be confusing:

.. code-block:: c++

  if (b) {
    [[unlikely]] --b; // In the path of execution,
                      // this branch is considered unlikely.
  }

  if (b) {
    --b;
    if(b)
      return;
    [[unlikely]] --b; // Not in the path of execution,
  }                   // the branch has no likelihood information.

  if (b) {
    --b;
    foo(b);
    // Whether or not the next statement is in the path of execution depends
    // on the declaration of foo():
    // In the path of execution: void foo(int);
    // Not in the path of execution: [[noreturn]] void foo(int);
    // This means the likelihood of the branch depends on the declaration
    // of foo().
    [[unlikely]] --b;
  }


Below are some example usages of the likelihood attributes and their effects:

.. code-block:: c++

  if (b) [[likely]] { // Placement on the first statement in the branch.
    // The compiler will optimize to execute the code here.
  } else {
  }

  if (b)
    [[unlikely]] b++; // Placement on the first statement in the branch.
  else {
    // The compiler will optimize to execute the code here.
  }

  if (b) {
    [[unlikely]] b++; // Placement on the second statement in the branch.
  }                   // The attribute will be ignored.

  if (b) [[likely]] {
    [[unlikely]] b++; // No contradiction since the second attribute
  }                   // is ignored.

  if (b)
    ;
  else [[likely]] {
    // The compiler will optimize to execute the code here.
  }

  if (b)
    ;
  else
    // The compiler will optimize to execute the next statement.
    [[likely]] b = f();

  if (b) [[likely]]; // Both branches are likely. A diagnostic is issued
  else [[likely]];   // and the attributes are ignored.

  if (b)
    [[likely]] int i = 5; // Issues a diagnostic since the attribute
                          // isn't allowed on a declaration.

  switch (i) {
    [[likely]] case 1:    // This value is likely
      ...
      break;

    [[unlikely]] case 2:  // This value is unlikely
      ...
      [[fallthrough]];

    case 3:               // No likelihood attribute
      ...
      [[likely]] break;   // No effect

    case 4: [[likely]] {  // attribute on substatement has no effect
      ...
      break;
      }

    [[unlikely]] default: // All other values are unlikely
      ...
      break;
  }

  switch (i) {
    [[likely]] case 0:    // This value and code path is likely
      ...
      [[fallthrough]];

    case 1:               // No likelihood attribute, code path is neutral
      break;              // falling through has no effect on the likelihood

    case 2:               // No likelihood attribute, code path is neutral
      [[fallthrough]];

    [[unlikely]] default: // This value and code path are both unlikely
      break;
  }

  for(int i = 0; i != size; ++i) [[likely]] {
    ...               // The loop is the likely path of execution
  }

  for(const auto &E : Elements) [[likely]] {
    ...               // The loop is the likely path of execution
  }

  while(i != size) [[unlikely]] {
    ...               // The loop is the unlikely path of execution
  }                   // The generated code will optimize to skip the loop body

  while(true) [[unlikely]] {
    ...               // The attribute has no effect
  }                   // Clang elides the comparison and generates an infinite
                      // loop

  }];
}

def ARMInterruptDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "interrupt (ARM)";
  let Content = [{
Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
ARM targets. This attribute may be attached to a function definition and
instructs the backend to generate appropriate function entry/exit code so that
it can be used directly as an interrupt service routine.

The parameter passed to the interrupt attribute is optional, but if
provided it must be a string literal with one of the following values: "IRQ",
"FIQ", "SWI", "ABORT", "UNDEF".

The semantics are as follows:

- If the function is AAPCS, Clang instructs the backend to realign the stack to
  8 bytes on entry. This is a general requirement of the AAPCS at public
  interfaces, but may not hold when an exception is taken. Doing this allows
  other AAPCS functions to be called.
- If the CPU is M-class this is all that needs to be done since the architecture
  itself is designed in such a way that functions obeying the normal AAPCS ABI
  constraints are valid exception handlers.
- If the CPU is not M-class, the prologue and epilogue are modified to save all
  non-banked registers that are used, so that upon return the user-mode state
  will not be corrupted. Note that to avoid unnecessary overhead, only
  general-purpose (integer) registers are saved in this way. If VFP operations
  are needed, that state must be saved manually.

  Specifically, interrupt kinds other than "FIQ" will save all core registers
  except "lr" and "sp". "FIQ" interrupts will save r0-r7.
- If the CPU is not M-class, the return instruction is changed to one of the
  canonical sequences permitted by the architecture for exception return. Where
  possible the function itself will make the necessary "lr" adjustments so that
  the "preferred return address" is selected.

  Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
  handler, where the offset from "lr" to the preferred return address depends on
  the execution state of the code which generated the exception. In this case
  a sequence equivalent to "movs pc, lr" will be used.
  }];
}

def BPFPreserveAccessIndexDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((preserve_access_index))``
attribute for the BPF target. This attribute may be attached to a
struct or union declaration, where if -g is specified, it enables
preserving struct or union member access debuginfo indices of this
struct or union, similar to clang ``__builtin_preserve_access_index()``.
  }];
}

def MipsInterruptDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "interrupt (MIPS)";
  let Content = [{
Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on
MIPS targets. This attribute may be attached to a function definition and instructs
the backend to generate appropriate function entry/exit code so that it can be used
directly as an interrupt service routine.

By default, the compiler will produce a function prologue and epilogue suitable for
an interrupt service routine that handles an External Interrupt Controller (eic)
generated interrupt. This behavior can be explicitly requested with the "eic"
argument.

Otherwise, for use with vectored interrupt mode, the argument passed should be
of the form "vector=LEVEL" where LEVEL is one of the following values:
"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will
then set the interrupt mask to the corresponding level which will mask all
interrupts up to and including the argument.

The semantics are as follows:

- The prologue is modified so that the Exception Program Counter (EPC) and
  Status coprocessor registers are saved to the stack. The interrupt mask is
  set so that the function can only be interrupted by a higher priority
  interrupt. The epilogue will restore the previous values of EPC and Status.

- The prologue and epilogue are modified to save and restore all non-kernel
  registers as necessary.

- The FPU is disabled in the prologue, as the floating pointer registers are not
  spilled to the stack.

- The function return sequence is changed to use an exception return instruction.

- The parameter sets the interrupt mask for the function corresponding to the
  interrupt level specified. If no mask is specified the interrupt mask
  defaults to "eic".
  }];
}

def MicroMipsDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the GNU style ``__attribute__((micromips))`` and
``__attribute__((nomicromips))`` attributes on MIPS targets. These attributes
may be attached to a function definition and instructs the backend to generate
or not to generate microMIPS code for that function.

These attributes override the ``-mmicromips`` and ``-mno-micromips`` options
on the command line.
  }];
}

def MipsLongCallStyleDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "long_call, far";
  let Content = [{
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
and ``__attribute__((near))`` attributes on MIPS targets. These attributes may
only be added to function declarations and change the code generated
by the compiler when directly calling the function. The ``near`` attribute
allows calls to the function to be made using the ``jal`` instruction, which
requires the function to be located in the same naturally aligned 256MB
segment as the caller. The ``long_call`` and ``far`` attributes are synonyms
and require the use of a different call sequence that works regardless
of the distance between the functions.

These attributes have no effect for position-independent code.

These attributes take priority over command line switches such
as ``-mlong-calls`` and ``-mno-long-calls``.
  }];
}

def MipsShortCallStyleDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "short_call, near";
  let Content = [{
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
``__attribute__((short__call))``, and ``__attribute__((near))`` attributes
on MIPS targets. These attributes may only be added to function declarations
and change the code generated by the compiler when directly calling
the function. The ``short_call`` and ``near`` attributes are synonyms and
allow calls to the function to be made using the ``jal`` instruction, which
requires the function to be located in the same naturally aligned 256MB segment
as the caller. The ``long_call`` and ``far`` attributes are synonyms and
require the use of a different call sequence that works regardless
of the distance between the functions.

These attributes have no effect for position-independent code.

These attributes take priority over command line switches such
as ``-mlong-calls`` and ``-mno-long-calls``.
  }];
}

def RISCVInterruptDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "interrupt (RISCV)";
  let Content = [{
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on RISCV
targets. This attribute may be attached to a function definition and instructs
the backend to generate appropriate function entry/exit code so that it can be
used directly as an interrupt service routine.

Permissible values for this parameter are ``user``, ``supervisor``,
and ``machine``. If there is no parameter, then it defaults to machine.

Repeated interrupt attribute on the same declaration will cause a warning
to be emitted. In case of repeated declarations, the last one prevails.

Refer to:
https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html
https://riscv.org/specifications/privileged-isa/
The RISC-V Instruction Set Manual Volume II: Privileged Architecture
Version 1.10.
  }];
}

def AVRInterruptDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "interrupt (AVR)";
  let Content = [{
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
AVR targets. This attribute may be attached to a function definition and instructs
the backend to generate appropriate function entry/exit code so that it can be used
directly as an interrupt service routine.

On the AVR, the hardware globally disables interrupts when an interrupt is executed.
The first instruction of an interrupt handler declared with this attribute is a SEI
instruction to re-enable interrupts. See also the signal attribute that
does not insert a SEI instruction.
  }];
}

def AVRSignalDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the GNU style ``__attribute__((signal))`` attribute on
AVR targets. This attribute may be attached to a function definition and instructs
the backend to generate appropriate function entry/exit code so that it can be used
directly as an interrupt service routine.

Interrupt handler functions defined with the signal attribute do not re-enable interrupts.
}];
}

def TargetDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute.
This attribute may be attached to a function definition and instructs
the backend to use different code generation options than were passed on the
command line.

The current set of options correspond to the existing "subtarget features" for
the target with or without a "-mno-" in front corresponding to the absence
of the feature, as well as ``arch="CPU"`` which will change the default "CPU"
for the function.

For X86, the attribute also allows ``tune="CPU"`` to optimize the generated
code for the given CPU without changing the available instructions.

For AArch64, the attribute also allows the "branch-protection=<args>" option,
where the permissible arguments and their effect on code generation are the same
as for the command-line option ``-mbranch-protection``.

Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2",
"avx", "xop" and largely correspond to the machine specific options handled by
the front end.

Additionally, this attribute supports function multiversioning for ELF based
x86/x86-64 targets, which can be used to create multiple implementations of the
same function that will be resolved at runtime based on the priority of their
``target`` attribute strings. A function is considered a multiversioned function
if either two declarations of the function have different ``target`` attribute
strings, or if it has a ``target`` attribute string of ``default``. For
example:

  .. code-block:: c++

    __attribute__((target("arch=atom")))
    void foo() {} // will be called on 'atom' processors.
    __attribute__((target("default")))
    void foo() {} // will be called on any other processors.

All multiversioned functions must contain a ``default`` (fallback)
implementation, otherwise usages of the function are considered invalid.
Additionally, a function may not become multiversioned after its first use.
}];
}

def MinVectorWidthDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((min_vector_width(width)))`` attribute. This
attribute may be attached to a function and informs the backend that this
function desires vectors of at least this width to be generated. Target-specific
maximum vector widths still apply. This means even if you ask for something
larger than the target supports, you will only get what the target supports.
This attribute is meant to be a hint to control target heuristics that may
generate narrower vectors than what the target hardware supports.

This is currently used by the X86 target to allow some CPUs that support 512-bit
vectors to be limited to using 256-bit vectors to avoid frequency penalties.
This is currently enabled with the ``-prefer-vector-width=256`` command line
option. The ``min_vector_width`` attribute can be used to prevent the backend
from trying to split vector operations to match the ``prefer-vector-width``. All
X86 vector intrinsics from x86intrin.h already set this attribute. Additionally,
use of any of the X86-specific vector builtins will implicitly set this
attribute on the calling function. The intent is that explicitly writing vector
code using the X86 intrinsics will prevent ``prefer-vector-width`` from
affecting the code.
}];
}

def DocCatAMDGPUAttributes : DocumentationCategory<"AMD GPU Attributes">;

def AMDGPUFlatWorkGroupSizeDocs : Documentation {
  let Category = DocCatAMDGPUAttributes;
  let Content = [{
The flat work-group size is the number of work-items in the work-group size
specified when the kernel is dispatched. It is the product of the sizes of the
x, y, and z dimension of the work-group.

Clang supports the
``__attribute__((amdgpu_flat_work_group_size(<min>, <max>)))`` attribute for the
AMDGPU target. This attribute may be attached to a kernel function definition
and is an optimization hint.

``<min>`` parameter specifies the minimum flat work-group size, and ``<max>``
parameter specifies the maximum flat work-group size (must be greater than
``<min>``) to which all dispatches of the kernel will conform. Passing ``0, 0``
as ``<min>, <max>`` implies the default behavior (``128, 256``).

If specified, the AMDGPU target backend might be able to produce better machine
code for barriers and perform scratch promotion by estimating available group
segment size.

An error will be given if:
  - Specified values violate subtarget specifications;
  - Specified values are not compatible with values provided through other
    attributes.
  }];
}

def AMDGPUWavesPerEUDocs : Documentation {
  let Category = DocCatAMDGPUAttributes;
  let Content = [{
A compute unit (CU) is responsible for executing the wavefronts of a work-group.
It is composed of one or more execution units (EU), which are responsible for
executing the wavefronts. An EU can have enough resources to maintain the state
of more than one executing wavefront. This allows an EU to hide latency by
switching between wavefronts in a similar way to symmetric multithreading on a
CPU. In order to allow the state for multiple wavefronts to fit on an EU, the
resources used by a single wavefront have to be limited. For example, the number
of SGPRs and VGPRs. Limiting such resources can allow greater latency hiding,
but can result in having to spill some register state to memory.

Clang supports the ``__attribute__((amdgpu_waves_per_eu(<min>[, <max>])))``
attribute for the AMDGPU target. This attribute may be attached to a kernel
function definition and is an optimization hint.

``<min>`` parameter specifies the requested minimum number of waves per EU, and
*optional* ``<max>`` parameter specifies the requested maximum number of waves
per EU (must be greater than ``<min>`` if specified). If ``<max>`` is omitted,
then there is no restriction on the maximum number of waves per EU other than
the one dictated by the hardware for which the kernel is compiled. Passing
``0, 0`` as ``<min>, <max>`` implies the default behavior (no limits).

If specified, this attribute allows an advanced developer to tune the number of
wavefronts that are capable of fitting within the resources of an EU. The AMDGPU
target backend can use this information to limit resources, such as number of
SGPRs, number of VGPRs, size of available group and private memory segments, in
such a way that guarantees that at least ``<min>`` wavefronts and at most
``<max>`` wavefronts are able to fit within the resources of an EU. Requesting
more wavefronts can hide memory latency but limits available registers which
can result in spilling. Requesting fewer wavefronts can help reduce cache
thrashing, but can reduce memory latency hiding.

This attribute controls the machine code generated by the AMDGPU target backend
to ensure it is capable of meeting the requested values. However, when the
kernel is executed, there may be other reasons that prevent meeting the request,
for example, there may be wavefronts from other kernels executing on the EU.

An error will be given if:
  - Specified values violate subtarget specifications;
  - Specified values are not compatible with values provided through other
    attributes;
  - The AMDGPU target backend is unable to create machine code that can meet the
    request.
  }];
}

def AMDGPUNumSGPRNumVGPRDocs : Documentation {
  let Category = DocCatAMDGPUAttributes;
  let Content = [{
Clang supports the ``__attribute__((amdgpu_num_sgpr(<num_sgpr>)))`` and
``__attribute__((amdgpu_num_vgpr(<num_vgpr>)))`` attributes for the AMDGPU
target. These attributes may be attached to a kernel function definition and are
an optimization hint.

If these attributes are specified, then the AMDGPU target backend will attempt
to limit the number of SGPRs and/or VGPRs used to the specified value(s). The
number of used SGPRs and/or VGPRs may further be rounded up to satisfy the
allocation requirements or constraints of the subtarget. Passing ``0`` as
``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits).

These attributes can be used to test the AMDGPU target backend. It is
recommended that the ``amdgpu_waves_per_eu`` attribute be used to control
resources such as SGPRs and VGPRs since it is aware of the limits for different
subtargets.

An error will be given if:
  - Specified values violate subtarget specifications;
  - Specified values are not compatible with values provided through other
    attributes;
  - The AMDGPU target backend is unable to create machine code that can meet the
    request.
  }];
}

def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> {
  let Content = [{
Clang supports several different calling conventions, depending on the target
platform and architecture. The calling convention used for a function determines
how parameters are passed, how results are returned to the caller, and other
low-level details of calling a function.
  }];
}

def PcsDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On ARM targets, this attribute can be used to select calling conventions
similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
"aapcs-vfp".
  }];
}

def AArch64VectorPcsDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On AArch64 targets, this attribute changes the calling convention of a
function to preserve additional floating-point and Advanced SIMD registers
relative to the default calling convention used for AArch64.

This means it is more efficient to call such functions from code that performs
extensive floating-point and vector calculations, because fewer live SIMD and FP
registers need to be saved. This property makes it well-suited for e.g.
floating-point or vector math library functions, which are typically leaf
functions that require a small number of registers.

However, using this attribute also means that it is more expensive to call
a function that adheres to the default calling convention from within such
a function. Therefore, it is recommended that this attribute is only used
for leaf functions.

For more information, see the documentation for `aarch64_vector_pcs`_ on
the Arm Developer website.

.. _`aarch64_vector_pcs`: https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi
  }];
}

def RegparmDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On 32-bit x86 targets, the regparm attribute causes the compiler to pass
the first three integer parameters in EAX, EDX, and ECX instead of on the
stack. This attribute has no effect on variadic functions, and all parameters
are passed via the stack as normal.
  }];
}

def SysVABIDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On Windows x86_64 targets, this attribute changes the calling convention of a
function to match the default convention used on Sys V targets such as Linux,
Mac, and BSD. This attribute has no effect on other targets.
  }];
}

def MSABIDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On non-Windows x86_64 targets, this attribute changes the calling convention of
a function to match the default convention used on Windows x86_64. This
attribute has no effect on Windows targets or non-x86_64 targets.
  }];
}

def StdCallDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On 32-bit x86 targets, this attribute changes the calling convention of a
function to clear parameters off of the stack on return. This convention does
not support variadic calls or unprototyped functions in C, and has no effect on
x86_64 targets. This calling convention is used widely by the Windows API and
COM applications. See the documentation for `__stdcall`_ on MSDN.

.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
  }];
}

def FastCallDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On 32-bit x86 targets, this attribute changes the calling convention of a
function to use ECX and EDX as register parameters and clear parameters off of
the stack on return. This convention does not support variadic calls or
unprototyped functions in C, and has no effect on x86_64 targets. This calling
convention is supported primarily for compatibility with existing code. Users
seeking register parameters should use the ``regparm`` attribute, which does
not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN.

.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx
  }];
}

def RegCallDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On x86 targets, this attribute changes the calling convention to
`__regcall`_ convention. This convention aims to pass as many arguments
as possible in registers. It also tries to utilize registers for the
return value whenever it is possible.

.. _`__regcall`: https://software.intel.com/en-us/node/693069
  }];
}

def ThisCallDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On 32-bit x86 targets, this attribute changes the calling convention of a
function to use ECX for the first parameter (typically the implicit ``this``
parameter of C++ methods) and clear parameters off of the stack on return. This
convention does not support variadic calls or unprototyped functions in C, and
has no effect on x86_64 targets. See the documentation for `__thiscall`_ on
MSDN.

.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx
  }];
}

def VectorCallDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On 32-bit x86 *and* x86_64 targets, this attribute changes the calling
convention of a function to pass vector parameters in SSE registers.

On 32-bit x86 targets, this calling convention is similar to ``__fastcall``.
The first two integer parameters are passed in ECX and EDX. Subsequent integer
parameters are passed in memory, and callee clears the stack. On x86_64
targets, the callee does *not* clear the stack, and integer parameters are
passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling
convention.

On both 32-bit x86 and x86_64 targets, vector and floating point arguments are
passed in XMM0-XMM5. Homogeneous vector aggregates of up to four elements are
passed in sequential SSE registers if enough are available. If AVX is enabled,
256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that
cannot be passed in registers for any reason is passed by reference, which
allows the caller to align the parameter memory.

See the documentation for `__vectorcall`_ on MSDN for more details.

.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx
  }];
}

def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
  let Content = [{
Clang supports additional attributes for checking basic resource management
properties, specifically for unique objects that have a single owning reference.
The following attributes are currently supported, although **the implementation
for these annotations is currently in development and are subject to change.**
  }];
}

def SetTypestateDocs : Documentation {
  let Category = DocCatConsumed;
  let Content = [{
Annotate methods that transition an object into a new state with
``__attribute__((set_typestate(new_state)))``. The new state must be
unconsumed, consumed, or unknown.
  }];
}

def CallableWhenDocs : Documentation {
  let Category = DocCatConsumed;
  let Content = [{
Use ``__attribute__((callable_when(...)))`` to indicate what states a method
may be called in. Valid states are unconsumed, consumed, or unknown. Each
argument to this attribute must be a quoted string. E.g.:

``__attribute__((callable_when("unconsumed", "unknown")))``
  }];
}

def TestTypestateDocs : Documentation {
  let Category = DocCatConsumed;
  let Content = [{
Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method
returns true if the object is in the specified state..
  }];
}

def ParamTypestateDocs : Documentation {
  let Category = DocCatConsumed;
  let Content = [{
This attribute specifies expectations about function parameters. Calls to an
function with annotated parameters will issue a warning if the corresponding
argument isn't in the expected state. The attribute is also used to set the
initial state of the parameter when analyzing the function's body.
  }];
}

def ReturnTypestateDocs : Documentation {
  let Category = DocCatConsumed;
  let Content = [{
The ``return_typestate`` attribute can be applied to functions or parameters.
When applied to a function the attribute specifies the state of the returned
value. The function's body is checked to ensure that it always returns a value
in the specified state. On the caller side, values returned by the annotated
function are initialized to the given state.

When applied to a function parameter it modifies the state of an argument after
a call to the function returns. The function's body is checked to ensure that
the parameter is in the expected state before returning.
  }];
}

def ConsumableDocs : Documentation {
  let Category = DocCatConsumed;
  let Content = [{
Each ``class`` that uses any of the typestate annotations must first be marked
using the ``consumable`` attribute. Failure to do so will result in a warning.

This attribute accepts a single parameter that must be one of the following:
``unknown``, ``consumed``, or ``unconsumed``.
  }];
}

def NoSanitizeDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use the ``no_sanitize`` attribute on a function or a global variable
declaration to specify that a particular instrumentation or set of
instrumentations should not be applied. 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 or variable.

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
  // heading to be specified. The most common spelling is sufficient.
  let Heading = "no_sanitize_address, no_address_safety_analysis";
  let Content = [{
.. _langext-address_sanitizer:

Use ``__attribute__((no_sanitize_address))`` on a function or a global
variable declaration to specify that address safety instrumentation
(e.g. AddressSanitizer) should not be applied.
  }];
}

def NoSanitizeThreadDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "no_sanitize_thread";
  let Content = [{
.. _langext-thread_sanitizer:

Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
specify that checks for data races on plain (non-atomic) memory accesses should
not be inserted by ThreadSanitizer. The function is still instrumented by the
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:

Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
specify that checks for uninitialized memory should not be inserted
(e.g. by MemorySanitizer). The function may still be instrumented by the tool
to avoid false positives in other places.
  }];
}

def CFICanonicalJumpTableDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "cfi_canonical_jump_table";
  let Content = [{
.. _langext-cfi_canonical_jump_table:

Use ``__attribute__((cfi_canonical_jump_table))`` on a function declaration to
make the function's CFI jump table canonical. See :ref:`the CFI documentation
<cfi-canonical-jump-tables>` for more details.
  }];
}

def DocCatTypeSafety : DocumentationCategory<"Type Safety Checking"> {
  let Content = [{
Clang supports additional attributes to enable checking type safety properties
that can't be enforced by the C type system. To see warnings produced by these
checks, ensure that -Wtype-safety is enabled. Use cases include:

* MPI library implementations, where these attributes enable checking that
  the buffer type matches the passed ``MPI_Datatype``;
* for HDF5 library there is a similar use case to MPI;
* checking types of variadic functions' arguments for functions like
  ``fcntl()`` and ``ioctl()``.

You can detect support for these attributes with ``__has_attribute()``. For
example:

.. code-block:: c++

  #if defined(__has_attribute)
  #  if __has_attribute(argument_with_type_tag) && \
        __has_attribute(pointer_with_type_tag) && \
        __has_attribute(type_tag_for_datatype)
  #    define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
  /* ... other macros ... */
  #  endif
  #endif

  #if !defined(ATTR_MPI_PWT)
  # define ATTR_MPI_PWT(buffer_idx, type_idx)
  #endif

  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
      ATTR_MPI_PWT(1,3);
  }];
}

def ArgumentWithTypeTagDocs : Documentation {
  let Category = DocCatTypeSafety;
  let Heading = "argument_with_type_tag";
  let Content = [{
Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
type_tag_idx)))`` on a function declaration to specify that the function
accepts a type tag that determines the type of some other argument.

This attribute is primarily useful for checking arguments of variadic functions
(``pointer_with_type_tag`` can be used in most non-variadic cases).

In the attribute prototype above:
  * ``arg_kind`` is an identifier that should be used when annotating all
    applicable type tags.
  * ``arg_idx`` provides the position of a function argument. The expected type of
    this function argument will be determined by the function argument specified
    by ``type_tag_idx``. In the code example below, "3" means that the type of the
    function's third argument will be determined by ``type_tag_idx``.
  * ``type_tag_idx`` provides the position of a function argument. This function
    argument will be a type tag. The type tag will determine the expected type of
    the argument specified by ``arg_idx``. In the code example below, "2" means
    that the type tag associated with the function's second argument should agree
    with the type of the argument specified by ``arg_idx``.

For example:

.. code-block:: c++

  int fcntl(int fd, int cmd, ...)
      __attribute__(( argument_with_type_tag(fcntl,3,2) ));
  // The function's second argument will be a type tag; this type tag will
  // determine the expected type of the function's third argument.
  }];
}

def PointerWithTypeTagDocs : Documentation {
  let Category = DocCatTypeSafety;
  let Heading = "pointer_with_type_tag";
  let Content = [{
Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
on a function declaration to specify that the function accepts a type tag that
determines the pointee type of some other pointer argument.

In the attribute prototype above:
  * ``ptr_kind`` is an identifier that should be used when annotating all
    applicable type tags.
  * ``ptr_idx`` provides the position of a function argument; this function
    argument will have a pointer type. The expected pointee type of this pointer
    type will be determined by the function argument specified by
    ``type_tag_idx``. In the code example below, "1" means that the pointee type
    of the function's first argument will be determined by ``type_tag_idx``.
  * ``type_tag_idx`` provides the position of a function argument; this function
    argument will be a type tag. The type tag will determine the expected pointee
    type of the pointer argument specified by ``ptr_idx``. In the code example
    below, "3" means that the type tag associated with the function's third
    argument should agree with the pointee type of the pointer argument specified
    by ``ptr_idx``.

For example:

.. code-block:: c++

  typedef int MPI_Datatype;
  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
      __attribute__(( pointer_with_type_tag(mpi,1,3) ));
  // The function's 3rd argument will be a type tag; this type tag will
  // determine the expected pointee type of the function's 1st argument.
  }];
}

def TypeTagForDatatypeDocs : Documentation {
  let Category = DocCatTypeSafety;
  let Content = [{
When declaring a variable, use
``__attribute__((type_tag_for_datatype(kind, type)))`` to create a type tag that
is tied to the ``type`` argument given to the attribute.

In the attribute prototype above:
  * ``kind`` is an identifier that should be used when annotating all applicable
    type tags.
  * ``type`` indicates the name of the type.

Clang supports annotating type tags of two forms.

  * **Type tag that is a reference to a declared identifier.**
    Use ``__attribute__((type_tag_for_datatype(kind, type)))`` when declaring that
    identifier:

    .. code-block:: c++

      typedef int MPI_Datatype;
      extern struct mpi_datatype mpi_datatype_int
          __attribute__(( type_tag_for_datatype(mpi,int) ));
      #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
      // &mpi_datatype_int is a type tag. It is tied to type "int".

  * **Type tag that is an integral literal.**
    Declare a ``static const`` variable with an initializer value and attach
    ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration:

    .. code-block:: c++

      typedef int MPI_Datatype;
      static const MPI_Datatype mpi_datatype_int
          __attribute__(( type_tag_for_datatype(mpi,int) )) = 42;
      #define MPI_INT ((MPI_Datatype) 42)
      // The number 42 is a type tag. It is tied to type "int".


The ``type_tag_for_datatype`` attribute also accepts an optional third argument
that determines how the type of the function argument specified by either
``arg_idx`` or ``ptr_idx`` is compared against the type associated with the type
tag. (Recall that for the ``argument_with_type_tag`` attribute, the type of the
function argument specified by ``arg_idx`` is compared against the type
associated with the type tag. Also recall that for the ``pointer_with_type_tag``
attribute, the pointee type of the function argument specified by ``ptr_idx`` is
compared against the type associated with the type tag.) There are two supported
values for this optional third argument:

  * ``layout_compatible`` will cause types to be compared according to
    layout-compatibility rules (In C++11 [class.mem] p 17, 18, see the
    layout-compatibility rules for two standard-layout struct types and for two
    standard-layout union types). This is useful when creating a type tag
    associated with a struct or union type. For example:

    .. code-block:: c++

      /* In mpi.h */
      typedef int MPI_Datatype;
      struct internal_mpi_double_int { double d; int i; };
      extern struct mpi_datatype mpi_datatype_double_int
          __attribute__(( type_tag_for_datatype(mpi,
                          struct internal_mpi_double_int, layout_compatible) ));

      #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)

      int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...)
          __attribute__(( pointer_with_type_tag(mpi,1,3) ));

      /* In user code */
      struct my_pair { double a; int b; };
      struct my_pair *buffer;
      MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning because the
                                                       // layout of my_pair is
                                                       // compatible with that of
                                                       // internal_mpi_double_int

      struct my_int_pair { int a; int b; }
      struct my_int_pair *buffer2;
      MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning because the
                                                        // layout of my_int_pair
                                                        // does not match that of
                                                        // internal_mpi_double_int

  * ``must_be_null`` specifies that the function argument specified by either
    ``arg_idx`` (for the ``argument_with_type_tag`` attribute) or ``ptr_idx`` (for
    the ``pointer_with_type_tag`` attribute) should be a null pointer constant.
    The second argument to the ``type_tag_for_datatype`` attribute is ignored. For
    example:

    .. code-block:: c++

      /* In mpi.h */
      typedef int MPI_Datatype;
      extern struct mpi_datatype mpi_datatype_null
          __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));

      #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
      int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...)
          __attribute__(( pointer_with_type_tag(mpi,1,3) ));

      /* In user code */
      struct my_pair { double a; int b; };
      struct my_pair *buffer;
      MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
                                                          // was specified but buffer
                                                          // is not a null pointer
  }];
}

def FlattenDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``flatten`` attribute causes calls within the attributed function to
be inlined unless it is impossible to do so, for example if the body of the
callee is unavailable or if the callee has the ``noinline`` attribute.
  }];
}

def FormatDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{

Clang supports the ``format`` attribute, which indicates that the function
accepts a ``printf`` or ``scanf``-like format string and corresponding
arguments or a ``va_list`` that contains these arguments.

Please see `GCC documentation about format attribute
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
about attribute syntax.

Clang implements two kinds of checks with this attribute.

#. Clang checks that the function with the ``format`` attribute is called with
   a format string that uses format specifiers that are allowed, and that
   arguments match the format string. This is the ``-Wformat`` warning, it is
   on by default.

#. Clang checks that the format string argument is a literal string. This is
   the ``-Wformat-nonliteral`` warning, it is off by default.

   Clang implements this mostly the same way as GCC, but there is a difference
   for functions that accept a ``va_list`` argument (for example, ``vprintf``).
   GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
   functions. Clang does not warn if the format string comes from a function
   parameter, where the function is annotated with a compatible attribute,
   otherwise it warns. For example:

   .. code-block:: c

     __attribute__((__format__ (__scanf__, 1, 3)))
     void foo(const char* s, char *buf, ...) {
       va_list ap;
       va_start(ap, buf);

       vprintf(s, ap); // warning: format string is not a string literal
     }

   In this case we warn because ``s`` contains a format string for a
   ``scanf``-like function, but it is passed to a ``printf``-like function.

   If the attribute is removed, clang still warns, because the format string is
   not a string literal.

   Another example:

   .. code-block:: c

     __attribute__((__format__ (__printf__, 1, 3)))
     void foo(const char* s, char *buf, ...) {
       va_list ap;
       va_start(ap, buf);

       vprintf(s, ap); // warning
     }

   In this case Clang does not warn because the format string ``s`` and
   the corresponding arguments are annotated. If the arguments are
   incorrect, the caller of ``foo`` will receive a warning.
  }];
}

def AlignValueDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The align_value attribute can be added to the typedef of a pointer type or the
declaration of a variable of pointer or reference type. It specifies that the
pointer will point to, or the reference will bind to, only objects with at
least the provided alignment. This alignment value must be some positive power
of 2.

   .. code-block:: c

     typedef double * aligned_double_ptr __attribute__((align_value(64)));
     void foo(double & x  __attribute__((align_value(128)),
              aligned_double_ptr y) { ... }

If the pointer value does not have the specified alignment at runtime, the
behavior of the program is undefined.
  }];
}

def FlagEnumDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute can be added to an enumerator to signal to the compiler that it
is intended to be used as a flag type. This will cause the compiler to assume
that the range of the type includes all of the values that you can get by
manipulating bits of the enumerator when issuing warnings.
  }];
}

def AsmLabelDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute can be used on a function or variable to specify its symbol name.

On some targets, all C symbols are prefixed by default with a single character,
typically ``_``. This was done historically to distinguish them from symbols
used by other languages. (This prefix is also added to the standard Itanium
C++ ABI prefix on "mangled" symbol names, so that e.g. on such targets the true
symbol name for a C++ variable declared as ``int cppvar;`` would be
``__Z6cppvar``; note the two underscores.)  This prefix is *not* added to the
symbol names specified by the ``asm`` attribute; programmers wishing to match a
C symbol name must compensate for this.

For example, consider the following C code:

.. code-block:: c

  int var1 asm("altvar") = 1;  // "altvar" in symbol table.
  int var2 = 1; // "_var2" in symbol table.

  void func1(void) asm("altfunc");
  void func1(void) {} // "altfunc" in symbol table.
  void func2(void) {} // "_func2" in symbol table.

Clang's implementation of this attribute is compatible with GCC's, `documented here <https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html>`_.

While it is possible to use this attribute to name a special symbol used
internally by the compiler, such as an LLVM intrinsic, this is neither
recommended nor supported and may cause the compiler to crash or miscompile.
Users who wish to gain access to intrinsic behavior are strongly encouraged to
request new builtin functions.
  }];
}

def EnumExtensibilityDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
Attribute ``enum_extensibility`` is used to distinguish between enum definitions
that are extensible and those that are not. The attribute can take either
``closed`` or ``open`` as an argument. ``closed`` indicates a variable of the
enum type takes a value that corresponds to one of the enumerators listed in the
enum definition or, when the enum is annotated with ``flag_enum``, a value that
can be constructed using values corresponding to the enumerators. ``open``
indicates a variable of the enum type can take any values allowed by the
standard and instructs clang to be more lenient when issuing warnings.

.. code-block:: c

  enum __attribute__((enum_extensibility(closed))) ClosedEnum {
    A0, A1
  };

  enum __attribute__((enum_extensibility(open))) OpenEnum {
    B0, B1
  };

  enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum {
    C0 = 1 << 0, C1 = 1 << 1
  };

  enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum {
    D0 = 1 << 0, D1 = 1 << 1
  };

  void foo1() {
    enum ClosedEnum ce;
    enum OpenEnum oe;
    enum ClosedFlagEnum cfe;
    enum OpenFlagEnum ofe;

    ce = A1;           // no warnings
    ce = 100;          // warning issued
    oe = B1;           // no warnings
    oe = 100;          // no warnings
    cfe = C0 | C1;     // no warnings
    cfe = C0 | C1 | 4; // warning issued
    ofe = D0 | D1;     // no warnings
    ofe = D0 | D1 | 4; // no warnings
  }

  }];
}

def EmptyBasesDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The empty_bases attribute permits the compiler to utilize the
empty-base-optimization more frequently.
This attribute only applies to struct, class, and union types.
It is only supported when using the Microsoft C++ ABI.
  }];
}

def LayoutVersionDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The layout_version attribute requests that the compiler utilize the class
layout rules of a particular compiler version.
This attribute only applies to struct, class, and union types.
It is only supported when using the Microsoft C++ ABI.
  }];
}

def LifetimeBoundDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``lifetimebound`` attribute on a function parameter or implicit object
parameter indicates that objects that are referred to by that parameter may
also be referred to by the return value of the annotated function (or, for a
parameter of a constructor, by the value of the constructed object). It is only
supported in C++.

By default, a reference is considered to refer to its referenced object, a
pointer is considered to refer to its pointee, a ``std::initializer_list<T>``
is considered to refer to its underlying array, and aggregates (arrays and
simple ``struct``s) are considered to refer to all objects that their
transitive subobjects refer to.

Clang warns if it is able to detect that an object or reference refers to
another object with a shorter lifetime. For example, Clang will warn if a
function returns a reference to a local variable, or if a reference is bound to
a temporary object whose lifetime is not extended. By using the
``lifetimebound`` attribute, this determination can be extended to look through
user-declared functions. For example:

.. code-block:: c++

    // Returns m[key] if key is present, or default_value if not.
    template<typename T, typename U>
    const U &get_or_default(const std::map<T, U> &m [[clang::lifetimebound]],
                            const T &key, /* note, not lifetimebound */
                            const U &default_value [[clang::lifetimebound]]);

    std::map<std::string, std::string> m;
    // warning: temporary "bar"s that might be bound to local reference 'val'
    // will be destroyed at the end of the full-expression
    const std::string &val = get_or_default(m, "foo"s, "bar"s);

    // No warning in this case.
    std::string def_val = "bar"s;
    const std::string &val = get_or_default(m, "foo"s, def_val);

The attribute can be applied to the implicit ``this`` parameter of a member
function by writing the attribute after the function type:

.. code-block:: c++

    struct string {
      // The returned pointer should not outlive ``*this``.
      const char *data() const [[clang::lifetimebound]];
    };

This attribute is inspired by the C++ committee paper `P0936R0
<http://wg21.link/p0936r0>`_, but does not affect whether temporary objects
have their lifetimes extended.
  }];
}

def TrivialABIDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union.
It instructs the compiler to pass and return the type using the C ABI for the
underlying type when the type would otherwise be considered non-trivial for the
purpose of calls.
A class annotated with ``trivial_abi`` can have non-trivial destructors or
copy/move constructors without automatically becoming non-trivial for the
purposes of calls. For example:

  .. code-block:: c++

    // A is trivial for the purposes of calls because ``trivial_abi`` makes the
    // user-provided special functions trivial.
    struct __attribute__((trivial_abi)) A {
      ~A();
      A(const A &);
      A(A &&);
      int x;
    };

    // B's destructor and copy/move constructor are considered trivial for the
    // purpose of calls because A is trivial.
    struct B {
      A a;
    };

If a type is trivial for the purposes of calls, has a non-trivial destructor,
and is passed as an argument by value, the convention is that the callee will
destroy the object before returning.

Attribute ``trivial_abi`` has no effect in the following cases:

- The class directly declares a virtual base or virtual methods.
- Copy constructors and move constructors of the class are all deleted.
- The class has a base class that is non-trivial for the purposes of calls.
- The class has a non-static data member whose type is non-trivial for the
  purposes of calls, which includes:

  - classes that are non-trivial for the purposes of calls
  - __weak-qualified types in Objective-C++
  - arrays of any of the above
  }];
}

def MSInheritanceDocs : Documentation {
  let Category = DocCatDecl;
  let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
  let Content = [{
This collection of keywords is enabled under ``-fms-extensions`` and controls
the pointer-to-member representation used on ``*-*-win32`` targets.

The ``*-*-win32`` targets utilize a pointer-to-member representation which
varies in size and alignment depending on the definition of the underlying
class.

However, this is problematic when a forward declaration is only available and
no definition has been made yet. In such cases, Clang is forced to utilize the
most general representation that is available to it.

These keywords make it possible to use a pointer-to-member representation other
than the most general one regardless of whether or not the definition will ever
be present in the current translation unit.

This family of keywords belong between the ``class-key`` and ``class-name``:

.. code-block:: c++

  struct __single_inheritance S;
  int S::*i;
  struct S {};

This keyword can be applied to class templates but only has an effect when used
on full specializations:

.. code-block:: c++

  template <typename T, typename U> struct __single_inheritance A; // warning: inheritance model ignored on primary template
  template <typename T> struct __multiple_inheritance A<T, T>; // warning: inheritance model ignored on partial specialization
  template <> struct __single_inheritance A<int, float>;

Note that choosing an inheritance model less general than strictly necessary is
an error:

.. code-block:: c++

  struct __multiple_inheritance S; // error: inheritance model does not match definition
  int S::*i;
  struct S {};
}];
}

def MSNoVTableDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute can be added to a class declaration or definition to signal to
the compiler that constructors and destructors will not reference the virtual
function table. It is only supported when using the Microsoft C++ ABI.
  }];
}

def OptnoneDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``optnone`` attribute suppresses essentially all optimizations
on a function or method, regardless of the optimization level applied to
the compilation unit as a whole. This is particularly useful when you
need to debug a particular function, but it is infeasible to build the
entire application without optimization. Avoiding optimization on the
specified function can improve the quality of the debugging information
for that function.

This attribute is incompatible with the ``always_inline`` and ``minsize``
attributes.
  }];
}

def LoopHintDocs : Documentation {
  let Category = DocCatStmt;
  let Heading = "#pragma clang loop";
  let Content = [{
The ``#pragma clang loop`` directive allows loop optimization hints to be
specified for the subsequent loop. The directive allows pipelining to be
disabled, or vectorization, vector predication, interleaving, and unrolling to
be enabled or disabled. Vector width, vector predication, interleave count,
unrolling count, and the initiation interval for pipelining can be explicitly
specified. See `language extensions
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
for details.
  }];
}

def UnrollHintDocs : Documentation {
  let Category = DocCatStmt;
  let Heading = "#pragma unroll, #pragma nounroll";
  let Content = [{
Loop unrolling optimization hints can be specified with ``#pragma unroll`` and
``#pragma nounroll``. The pragma is placed immediately before a for, while,
do-while, or c++11 range-based for loop.

Specifying ``#pragma unroll`` without a parameter directs the loop unroller to
attempt to fully unroll the loop if the trip count is known at compile time and
attempt to partially unroll the loop if the trip count is not known at compile
time:

.. code-block:: c++

  #pragma unroll
  for (...) {
    ...
  }

Specifying the optional parameter, ``#pragma unroll _value_``, directs the
unroller to unroll the loop ``_value_`` times. The parameter may optionally be
enclosed in parentheses:

.. code-block:: c++

  #pragma unroll 16
  for (...) {
    ...
  }

  #pragma unroll(16)
  for (...) {
    ...
  }

Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled:

.. code-block:: c++

  #pragma nounroll
  for (...) {
    ...
  }

``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
``#pragma clang loop unroll(full)`` and
``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll``
is equivalent to ``#pragma clang loop unroll(disable)``. See
`language extensions
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
for further details including limitations of the unroll hints.
  }];
}

def PipelineHintDocs : Documentation {
  let Category = DocCatStmt;
  let Heading = "#pragma clang loop pipeline, #pragma clang loop pipeline_initiation_interval";
  let Content = [{
    Software Pipelining optimization is a technique used to optimize loops by
  utilizing instruction-level parallelism. It reorders loop instructions to
  overlap iterations. As a result, the next iteration starts before the previous
  iteration has finished. The module scheduling technique creates a schedule for
  one iteration such that when repeating at regular intervals, no inter-iteration
  dependencies are violated. This constant interval(in cycles) between the start
  of iterations is called the initiation interval. i.e. The initiation interval
  is the number of cycles between two iterations of an unoptimized loop in the
  newly created schedule. A new, optimized loop is created such that a single iteration
  of the loop executes in the same number of cycles as the initiation interval.
    For further details see <https://llvm.org/pubs/2005-06-17-LattnerMSThesis-book.pdf>.

  ``#pragma clang loop pipeline and #pragma loop pipeline_initiation_interval``
  could be used as hints for the software pipelining optimization. The pragma is
  placed immediately before a for, while, do-while, or a C++11 range-based for
  loop.

  Using ``#pragma clang loop pipeline(disable)`` avoids the software pipelining
  optimization. The disable state can only be specified:

  .. code-block:: c++

  #pragma clang loop pipeline(disable)
  for (...) {
    ...
  }

  Using ``#pragma loop pipeline_initiation_interval`` instructs
  the software pipeliner to try the specified initiation interval.
  If a schedule was found then the resulting loop iteration would have
  the specified cycle count. If a schedule was not found then loop
  remains unchanged. The initiation interval must be a positive number
  greater than zero:

  .. code-block:: c++

  #pragma loop pipeline_initiation_interval(10)
  for (...) {
    ...
  }

  }];
}

def OpenCLUnrollHintDocs : Documentation {
  let Category = DocCatStmt;
  let Content = [{
The opencl_unroll_hint attribute qualifier can be used to specify that a loop
(for, while and do loops) can be unrolled. This attribute qualifier can be
used to specify full unrolling or partial unrolling by a specified amount.
This is a compiler hint and the compiler may ignore this directive. See
`OpenCL v2.0 <https://www.khronos.org/registry/cl/specs/opencl-2.0.pdf>`_
s6.11.5 for details.
  }];
}

def OpenCLIntelReqdSubGroupSizeDocs : Documentation {
  let Category = DocCatStmt;
  let Content = [{
The optional attribute intel_reqd_sub_group_size can be used to indicate that
the kernel must be compiled and executed with the specified subgroup size. When
this attribute is present, get_max_sub_group_size() is guaranteed to return the
specified integer value. This is important for the correctness of many subgroup
algorithms, and in some cases may be used by the compiler to generate more optimal
code. See `cl_intel_required_subgroup_size
<https://www.khronos.org/registry/OpenCL/extensions/intel/cl_intel_required_subgroup_size.txt>`
for details.
  }];
}

def OpenCLAccessDocs : Documentation {
  let Category = DocCatStmt;
  let Heading = "__read_only, __write_only, __read_write (read_only, write_only, read_write)";
  let Content = [{
The access qualifiers must be used with image object arguments or pipe arguments
to declare if they are being read or written by a kernel or function.

The read_only/__read_only, write_only/__write_only and read_write/__read_write
names are reserved for use as access qualifiers and shall not be used otherwise.

.. code-block:: c

  kernel void
  foo (read_only image2d_t imageA,
       write_only image2d_t imageB) {
    ...
  }

In the above example imageA is a read-only 2D image object, and imageB is a
write-only 2D image object.

The read_write (or __read_write) qualifier can not be used with pipe.

More details can be found in the OpenCL C language Spec v2.0, Section 6.6.
    }];
}

def DocOpenCLAddressSpaces : DocumentationCategory<"OpenCL Address Spaces"> {
  let Content = [{
The address space qualifier may be used to specify the region of memory that is
used to allocate the object. OpenCL supports the following address spaces:
__generic(generic), __global(global), __local(local), __private(private),
__constant(constant).

  .. code-block:: c

    __constant int c = ...;

    __generic int* foo(global int* g) {
      __local int* l;
      private int p;
      ...
      return l;
    }

More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
  }];
}

def OpenCLAddressSpaceGenericDocs : Documentation {
  let Category = DocOpenCLAddressSpaces;
  let Heading = "__generic, generic, [[clang::opencl_generic]]";
  let Content = [{
The generic address space attribute is only available with OpenCL v2.0 and later.
It can be used with pointer types. Variables in global and local scope and
function parameters in non-kernel functions can have the generic address space
type attribute. It is intended to be a placeholder for any other address space
except for '__constant' in OpenCL code which can be used with multiple address
spaces.
  }];
}

def OpenCLAddressSpaceConstantDocs : Documentation {
  let Category = DocOpenCLAddressSpaces;
  let Heading = "__constant, constant, [[clang::opencl_constant]]";
  let Content = [{
The constant address space attribute signals that an object is located in
a constant (non-modifiable) memory region. It is available to all work items.
Any type can be annotated with the constant address space attribute. Objects
with the constant address space qualifier can be declared in any scope and must
have an initializer.
  }];
}

def OpenCLAddressSpaceGlobalDocs : Documentation {
  let Category = DocOpenCLAddressSpaces;
  let Heading = "__global, global, [[clang::opencl_global]]";
  let Content = [{
The global address space attribute specifies that an object is allocated in
global memory, which is accessible by all work items. The content stored in this
memory area persists between kernel executions. Pointer types to the global
address space are allowed as function parameters or local variables. Starting
with OpenCL v2.0, the global address space can be used with global (program
scope) variables and static local variable as well.
  }];
}

def OpenCLAddressSpaceGlobalExtDocs : Documentation {
  let Category = DocOpenCLAddressSpaces;
  let Heading = "[[clang::opencl_global_device]], [[clang::opencl_global_host]]";
  let Content = [{
The ``global_device`` and ``global_host`` address space attributes specify that
an object is allocated in global memory on the device/host. It helps to
distinguish USM (Unified Shared Memory) pointers that access global device
memory from those that access global host memory. These new address spaces are
a subset of the ``__global/opencl_global`` address space, the full address space
set model for OpenCL 2.0 with the extension looks as follows:

  | generic->global->host
  |                ->device
  |        ->private
  |        ->local
  | constant

As ``global_device`` and ``global_host`` are a subset of
``__global/opencl_global`` address spaces it is allowed to convert
``global_device`` and ``global_host`` address spaces to
``__global/opencl_global`` address spaces (following ISO/IEC TR 18037 5.1.3
"Address space nesting and rules for pointers").
  }];
}

def OpenCLAddressSpaceLocalDocs : Documentation {
  let Category = DocOpenCLAddressSpaces;
  let Heading = "__local, local, [[clang::opencl_local]]";
  let Content = [{
The local address space specifies that an object is allocated in the local (work
group) memory area, which is accessible to all work items in the same work
group. The content stored in this memory region is not accessible after
the kernel execution ends. In a kernel function scope, any variable can be in
the local address space. In other scopes, only pointer types to the local address
space are allowed. Local address space variables cannot have an initializer.
  }];
}

def OpenCLAddressSpacePrivateDocs : Documentation {
  let Category = DocOpenCLAddressSpaces;
  let Heading = "__private, private, [[clang::opencl_private]]";
  let Content = [{
The private address space specifies that an object is allocated in the private
(work item) memory. Other work items cannot access the same memory area and its
content is destroyed after work item execution ends. Local variables can be
declared in the private address space. Function arguments are always in the
private address space. Kernel function arguments of a pointer or an array type
cannot point to the private address space.
  }];
}

def OpenCLNoSVMDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
OpenCL 2.0 supports the optional ``__attribute__((nosvm))`` qualifier for
pointer variable. It informs the compiler that the pointer does not refer
to a shared virtual memory region. See OpenCL v2.0 s6.7.2 for details.

Since it is not widely used and has been removed from OpenCL 2.1, it is ignored
by Clang.
  }];
}

def Ptr32Docs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``__ptr32`` qualifier represents a native pointer on a 32-bit system. On a
64-bit system, a pointer with ``__ptr32`` is extended to a 64-bit pointer. The
``__sptr`` and ``__uptr`` qualifiers can be used to specify whether the pointer
is sign extended or zero extended. This qualifier is enabled under
``-fms-extensions``.
  }];
}

def Ptr64Docs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``__ptr64`` qualifier represents a native pointer on a 64-bit system. On a
32-bit system, a ``__ptr64`` pointer is truncated to a 32-bit pointer. This
qualifier is enabled under ``-fms-extensions``.
  }];
}

def SPtrDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``__sptr`` qualifier specifies that a 32-bit pointer should be sign
extended when converted to a 64-bit pointer.
  }];
}

def UPtrDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``__uptr`` qualifier specifies that a 32-bit pointer should be zero
extended when converted to a 64-bit pointer.
  }];
}


def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> {
  let Content = [{
Whether a particular pointer may be "null" is an important concern when working
with pointers in the C family of languages. The various nullability attributes
indicate whether a particular pointer can be null or not, which makes APIs more
expressive and can help static analysis tools identify bugs involving null
pointers. Clang supports several kinds of nullability attributes: the 
``nonnull`` and ``returns_nonnull`` attributes indicate which function or
method parameters and result types can never be null, while nullability type
qualifiers indicate which pointer types can be null (``_Nullable``) or cannot
be null (``_Nonnull``).

The nullability (type) qualifiers express whether a value of a given pointer
type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning
for null (the ``_Nonnull`` qualifier), or for which the purpose of null is
unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers
are expressed within the type system, they are more general than the
``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for
example) a nullable pointer to an array of nonnull pointers. Nullability
qualifiers are written to the right of the pointer to which they apply. For
example:

  .. code-block:: c

    // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior).
    int fetch(int * _Nonnull ptr) { return *ptr; }

    // 'ptr' may be null.
    int fetch_or_zero(int * _Nullable ptr) {
      return ptr ? *ptr : 0;
    }

    // A nullable pointer to non-null pointers to const characters.
    const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n);

In Objective-C, there is an alternate spelling for the nullability qualifiers
that can be used in Objective-C methods and properties using context-sensitive,
non-underscored keywords. For example:

  .. code-block:: objective-c

    @interface NSView : NSResponder
      - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView;
      @property (assign, nullable) NSView *superview;
      @property (readonly, nonnull) NSArray *subviews;
    @end
  }];
}

def TypeNonNullDocs : Documentation {
  let Category = NullabilityDocs;
  let Content = [{
The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful
value for a value of the ``_Nonnull`` pointer type. For example, given a
declaration such as:

  .. code-block:: c

    int fetch(int * _Nonnull ptr);

a caller of ``fetch`` should not provide a null value, and the compiler will
produce a warning if it sees a literal null value passed to ``fetch``. Note
that, unlike the declaration attribute ``nonnull``, the presence of
``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch``
is free to consider null undefined behavior or (perhaps for
backward-compatibility reasons) defensively handle null.
  }];
}

def TypeNullableDocs : Documentation {
  let Category = NullabilityDocs;
  let Content = [{
The ``_Nullable`` nullability qualifier indicates that a value of the
``_Nullable`` pointer type can be null. For example, given:

  .. code-block:: c

    int fetch_or_zero(int * _Nullable ptr);

a caller of ``fetch_or_zero`` can provide null.
  }];
}

def TypeNullableResultDocs : Documentation {
  let Category = NullabilityDocs;
  let Content = [{
The ``_Nullable_result`` nullability qualifier means that a value of the
``_Nullable_result`` pointer can be ``nil``, just like ``_Nullable``. Where this
attribute differs from ``_Nullable`` is when it's used on a parameter to a
completion handler in a Swift async method. For instance, here:

  .. code-block:: objc

    -(void)fetchSomeDataWithID:(int)identifier
             completionHandler:(void (^)(Data *_Nullable_result result, NSError *error))completionHandler;

This method asynchronously calls ``completionHandler`` when the data is
available, or calls it with an error. ``_Nullable_result`` indicates to the
Swift importer that this is the uncommon case where ``result`` can get ``nil``
even if no error has occured, and will therefore import it as a Swift optional
type. Otherwise, if ``result`` was annotated with ``_Nullable``, the Swift
importer will assume that ``result`` will always be non-nil unless an error
occured.
}];
}

def TypeNullUnspecifiedDocs : Documentation {
  let Category = NullabilityDocs;
  let Content = [{
The ``_Null_unspecified`` nullability qualifier indicates that neither the
``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer
type. It is used primarily to indicate that the role of null with specific
pointers in a nullability-annotated header is unclear, e.g., due to
overly-complex implementations or historical factors with a long-lived API.
  }];
}

def NonNullDocs : Documentation {
  let Category = NullabilityDocs;
  let Content = [{
The ``nonnull`` attribute indicates that some function parameters must not be
null, and can be used in several different ways. It's original usage
(`from GCC <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes>`_)
is as a function (or Objective-C method) attribute that specifies which
parameters of the function are nonnull in a comma-separated list. For example:

  .. code-block:: c

    extern void * my_memcpy (void *dest, const void *src, size_t len)
                    __attribute__((nonnull (1, 2)));

Here, the ``nonnull`` attribute indicates that parameters 1 and 2
cannot have a null value. Omitting the parenthesized list of parameter indices
means that all parameters of pointer type cannot be null:

  .. code-block:: c

    extern void * my_memcpy (void *dest, const void *src, size_t len)
                    __attribute__((nonnull));

Clang also allows the ``nonnull`` attribute to be placed directly on a function
(or Objective-C method) parameter, eliminating the need to specify the
parameter index ahead of type. For example:

  .. code-block:: c

    extern void * my_memcpy (void *dest __attribute__((nonnull)),
                             const void *src __attribute__((nonnull)), size_t len);

Note that the ``nonnull`` attribute indicates that passing null to a non-null
parameter is undefined behavior, which the optimizer may take advantage of to,
e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a
pointer cannot be null in a more general manner (because it is part of the type
system) and does not imply undefined behavior, making it more widely applicable.
  }];
}

def ReturnsNonNullDocs : Documentation {
  let Category = NullabilityDocs;
  let Content = [{
The ``returns_nonnull`` attribute indicates that a particular function (or
Objective-C method) always returns a non-null pointer. For example, a
particular system ``malloc`` might be defined to terminate a process when
memory is not available rather than returning a null pointer:

  .. code-block:: c

    extern void * malloc (size_t size) __attribute__((returns_nonnull));

The ``returns_nonnull`` attribute implies that returning a null pointer is
undefined behavior, which the optimizer may take advantage of. The ``_Nonnull``
type qualifier indicates that a pointer cannot be null in a more general manner
(because it is part of the type system) and does not imply undefined behavior, 
making it more widely applicable
}];
}

def NoAliasDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``noalias`` attribute indicates that the only memory accesses inside
function are loads and stores from objects pointed to by its pointer-typed
arguments, with arbitrary offsets.
  }];
}

def NSErrorDomainDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
In Cocoa frameworks in Objective-C, one can group related error codes in enums
and categorize these enums with error domains.

The ``ns_error_domain`` attribute indicates a global ``NSString`` or
``CFString`` constant representing the error domain that an error code belongs
to. For pointer uniqueness and code size this is a constant symbol, not a
literal.

The domain and error code need to be used together. The ``ns_error_domain``
attribute links error codes to their domain at the source level.

This metadata is useful for documentation purposes, for static analysis, and for
improving interoperability between Objective-C and Swift. It is not used for
code generation in Objective-C.

For example:

  .. code-block:: objc

    #define NS_ERROR_ENUM(_type, _name, _domain)  \
      enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type

    extern NSString *const MyErrorDomain;
    typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
      MyErrFirst,
      MyErrSecond,
    };
  }];
}

def SwiftDocs : DocumentationCategory<"Customizing Swift Import"> {
  let Content = [{
Clang supports additional attributes for customizing how APIs are imported into
Swift.
  }];
}

def SwiftAsyncNameDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_async_name";
  let Content = [{
The ``swift_async_name`` attribute provides the name of the ``async`` overload for
the given declaration in Swift. If this attribute is absent, the name is
transformed according to the algorithm built into the Swift compiler.

The argument is a string literal that contains the Swift name of the function or
method. The name may be a compound Swift name. The function or method with such
an attribute must have more than zero parameters, as its last parameter is
assumed to be a callback that's eliminated in the Swift ``async`` name.

  .. code-block:: objc

    @interface URL
    + (void) loadContentsFrom:(URL *)url callback:(void (^)(NSData *))data __attribute__((__swift_async_name__("URL.loadContentsFrom(_:)")))
    @end
  }];
}

def SwiftAttrDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_attr";
  let Content = [{
The ``swift_attr`` provides a Swift-specific annotation for the declaration
to which the attribute appertains to. It can be used on any declaration
in Clang. This kind of annotation is ignored by Clang as it doesn't have any
semantic meaning in languages supported by Clang. The Swift compiler can
interpret these annotations according to its own rules when importing C or
Objective-C declarations.
}];
}

def SwiftBridgeDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_bridge";
  let Content = [{
The ``swift_bridge`` attribute indicates that the declaration to which the
attribute appertains is bridged to the named Swift type.

  .. code-block:: objc

    __attribute__((__objc_root__))
    @interface Base
    - (instancetype)init;
    @end

    __attribute__((__swift_bridge__("BridgedI")))
    @interface I : Base
    @end

In this example, the Objective-C interface ``I`` will be made available to Swift
with the name ``BridgedI``. It would be possible for the compiler to refer to
``I`` still in order to bridge the type back to Objective-C.
  }];
}

def SwiftBridgedTypedefDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_bridged";
  let Content = [{
The ``swift_bridged_typedef`` attribute indicates that when the typedef to which
the attribute appertains is imported into Swift, it should refer to the bridged
Swift type (e.g. Swift's ``String``) rather than the Objective-C type as written
(e.g. ``NSString``).

  .. code-block:: objc

    @interface NSString;
    typedef NSString *AliasedString __attribute__((__swift_bridged_typedef__));

    extern void acceptsAliasedString(AliasedString _Nonnull parameter);

In this case, the function ``acceptsAliasedString`` will be imported into Swift
as a function which accepts a ``String`` type parameter.
  }];
}

def SwiftObjCMembersDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_objc_members";
  let Content = [{
This attribute indicates that Swift subclasses and members of Swift extensions
of this class will be implicitly marked with the ``@objcMembers`` Swift
attribute, exposing them back to Objective-C.
  }];
}

def SwiftErrorDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_error";
  let Content = [{
The ``swift_error`` attribute controls whether a particular function (or
Objective-C method) is imported into Swift as a throwing function, and if so,
which dynamic convention it uses.

All of these conventions except ``none`` require the function to have an error
parameter. Currently, the error parameter is always the last parameter of type
``NSError**`` or ``CFErrorRef*``. Swift will remove the error parameter from
the imported API. When calling the API, Swift will always pass a valid address
initialized to a null pointer.

* ``swift_error(none)`` means that the function should not be imported as
  throwing. The error parameter and result type will be imported normally.

* ``swift_error(null_result)`` means that calls to the function should be
  considered to have thrown if they return a null value. The return type must be
  a pointer type, and it will be imported into Swift with a non-optional type.
  This is the default error convention for Objective-C methods that return
  pointers.

* ``swift_error(zero_result)`` means that calls to the function should be
  considered to have thrown if they return a zero result. The return type must be
  an integral type. If the return type would have been imported as ``Bool``, it
  is instead imported as ``Void``. This is the default error convention for
  Objective-C methods that return a type that would be imported as ``Bool``.

* ``swift_error(nonzero_result)`` means that calls to the function should be
  considered to have thrown if they return a non-zero result. The return type must
  be an integral type. If the return type would have been imported as ``Bool``,
  it is instead imported as ``Void``.

* ``swift_error(nonnull_error)`` means that calls to the function should be
  considered to have thrown if they leave a non-null error in the error parameter.
  The return type is left unmodified.

  }];
}

def SwiftNameDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_name";
  let Content = [{
The ``swift_name`` attribute provides the name of the declaration in Swift. If
this attribute is absent, the name is transformed according to the algorithm
built into the Swift compiler.

The argument is a string literal that contains the Swift name of the function,
variable, or type. When renaming a function, the name may be a compound Swift
name. For a type, enum constant, property, or variable declaration, the name
must be a simple or qualified identifier.

  .. code-block:: objc

    @interface URL
    - (void) initWithString:(NSString *)s __attribute__((__swift_name__("URL.init(_:)")))
    @end

    void __attribute__((__swift_name__("squareRoot()"))) sqrt(double v) {
    }
  }];
}

def SwiftNewTypeDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_newtype";
  let Content = [{
The ``swift_newtype`` attribute indicates that the typedef to which the
attribute appertains is imported as a new Swift type of the typedef's name.
Previously, the attribute was spelt ``swift_wrapper``. While the behaviour of
the attribute is identical with either spelling, ``swift_wrapper`` is
deprecated, only exists for compatibility purposes, and should not be used in
new code.

* ``swift_newtype(struct)`` means that a Swift struct will be created for this
  typedef.

* ``swift_newtype(enum)`` means that a Swift enum will be created for this
  typedef.

  .. code-block:: c

    // Import UIFontTextStyle as an enum type, with enumerated values being
    // constants.
    typedef NSString * UIFontTextStyle __attribute__((__swift_newtype__(enum)));

    // Import UIFontDescriptorFeatureKey as a structure type, with enumerated
    // values being members of the type structure.
    typedef NSString * UIFontDescriptorFeatureKey __attribute__((__swift_newtype__(struct)));

  }];
}

def SwiftPrivateDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_private";
  let Content = [{
Declarations marked with the ``swift_private`` attribute are hidden from the
framework client but are still made available for use within the framework or
Swift SDK overlay.

The purpose of this attribute is to permit a more idomatic implementation of
declarations in Swift while hiding the non-idiomatic one.
  }];
}

def OMPDeclareSimdDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "#pragma omp declare simd";
  let Content = [{
The ``declare simd`` construct can be applied to a function to enable the creation
of one or more versions that can process multiple arguments using SIMD
instructions from a single invocation in a SIMD loop. The ``declare simd``
directive is a declarative directive. There may be multiple ``declare simd``
directives for a function. The use of a ``declare simd`` construct on a function
enables the creation of SIMD versions of the associated function that can be
used to process multiple arguments from a single invocation from a SIMD loop
concurrently.
The syntax of the ``declare simd`` construct is as follows:

  .. code-block:: none

    #pragma omp declare simd [clause[[,] clause] ...] new-line
    [#pragma omp declare simd [clause[[,] clause] ...] new-line]
    [...]
    function definition or declaration

where clause is one of the following:

  .. code-block:: none

    simdlen(length)
    linear(argument-list[:constant-linear-step])
    aligned(argument-list[:alignment])
    uniform(argument-list)
    inbranch
    notinbranch

  }];
}

def OMPDeclareTargetDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "#pragma omp declare target";
  let Content = [{
The ``declare target`` directive specifies that variables and functions are mapped
to a device for OpenMP offload mechanism.

The syntax of the declare target directive is as follows:

  .. code-block:: c

    #pragma omp declare target new-line
    declarations-definition-seq
    #pragma omp end declare target new-line

or

  .. code-block:: c

    #pragma omp declare target (extended-list) new-line

or

  .. code-block:: c

    #pragma omp declare target clause[ [,] clause ... ] new-line

where clause is one of the following:


  .. code-block:: c

     to(extended-list)
     link(list)
     device_type(host | nohost | any)
  }];
}

def OMPDeclareVariantDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "#pragma omp declare variant";
  let Content = [{
The ``declare variant`` directive declares a specialized variant of a base
function and specifies the context in which that specialized variant is used.
The declare variant directive is a declarative directive.
The syntax of the ``declare variant`` construct is as follows:

  .. code-block:: none

    #pragma omp declare variant(variant-func-id) clause new-line
    [#pragma omp declare variant(variant-func-id) clause new-line]
    [...]
    function definition or declaration

where clause is one of the following:

  .. code-block:: none

    match(context-selector-specification)

and where ``variant-func-id`` is the name of a function variant that is either a
base language identifier or, for C++, a template-id.

Clang provides the following context selector extensions, used via
``implementation={extension(EXTENSION)}``:

  .. code-block:: none

    match_all
    match_any
    match_none
    disable_implicit_base
    allow_templates

The match extensions change when the *entire* context selector is considered a
match for an OpenMP context. The default is ``all``, with ``none`` no trait in the
selector is allowed to be in the OpenMP context, with ``any`` a single trait in
both the selector and OpenMP context is sufficient. Only a single match
extension trait is allowed per context selector.
The disable extensions remove default effects of the ``begin declare variant``
applied to a definition. If ``disable_implicit_base`` is given, we will not
introduce an implicit base function for a variant if no base function was
found. The variant is still generated but will never be called, due to the
absence of a base function and consequently calls to a base function.
The allow extensions change when the ``begin declare variant`` effect is
applied to a definition. If ``allow_templates`` is given, template function
definitions are considered as specializations of existing or assumed template
declarations with the same name. The template parameters for the base functions
are used to instantiate the specialization.

  }];
}

def LeafDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{

The ``leaf`` attribute is used as a compiler hint to improve dataflow analysis
in library functions. Functions marked with the ``leaf`` attribute are not allowed
to jump back into the caller's translation unit, whether through invoking a
callback function, an external function call, use of ``longjmp``, or other means.
Therefore, they cannot use or modify any data that does not escape the caller function's
compilation unit.

For more information see
`gcc documentation <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html>`
}];
}

def AssumptionDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "assume";
  let Content = [{
Clang supports the ``__attribute__((assume("assumption")))`` attribute to
provide additional information to the optimizer. The string-literal, here
"assumption", will be attached to the function declaration such that later
analysis and optimization passes can assume the "assumption" to hold.
This is similar to :ref:`__builtin_assume <langext-__builtin_assume>` but
instead of an expression that can be assumed to be non-zero, the assumption is
expressed as a string and it holds for the entire function.

A function can have multiple assume attributes and they propagate from prior
declarations to later definitions. Multiple assumptions are aggregated into a
single comma separated string. Thus, one can provide multiple assumptions via
a comma separated string, i.a.,
``__attribute__((assume("assumption1,assumption2")))``.

While LLVM plugins might provide more assumption strings, the default LLVM
optimization passes are aware of the following assumptions:

  .. code-block:: none

    "omp_no_openmp"
    "omp_no_openmp_routines"
    "omp_no_parallelism"

The OpenMP standard defines the meaning of OpenMP assumptions ("omp_XYZ" is
spelled "XYZ" in the `OpenMP 5.1 Standard`_).

.. _`OpenMP 5.1 Standard`: https://www.openmp.org/spec-html/5.1/openmpsu37.html#x56-560002.5.2

}];
}

def NoStackProtectorDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((no_stack_protector))`` attribute which disables
the stack protector on the specified function. This attribute is useful for
selectively disabling the stack protector on some functions when building with
``-fstack-protector`` compiler option.

For example, it disables the stack protector for the function ``foo`` but function
``bar`` will still be built with the stack protector with the ``-fstack-protector``
option.

.. code-block:: c

    int __attribute__((no_stack_protector))
    foo (int x); // stack protection will be disabled for foo.

    int bar(int y); // bar can be built with the stack protector.

    }];
}

def NotTailCalledDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``not_tail_called`` attribute prevents tail-call optimization on statically
bound calls. Objective-c methods, and functions marked as ``always_inline``
cannot be marked as ``not_tail_called``.

For example, it prevents tail-call optimization in the following case:

  .. code-block:: c

    int __attribute__((not_tail_called)) foo1(int);

    int foo2(int a) {
      return foo1(a); // No tail-call optimization on direct calls.
    }

However, it doesn't prevent tail-call optimization in this case:

  .. code-block:: c

    int __attribute__((not_tail_called)) foo1(int);

    int foo2(int a) {
      int (*fn)(int) = &foo1;

      // not_tail_called has no effect on an indirect call even if the call can
      // be resolved at compile time.
      return (*fn)(a);
    }

Generally, marking an overriding virtual function as ``not_tail_called`` is
not useful, because this attribute is a property of the static type. Calls
made through a pointer or reference to the base class type will respect
the ``not_tail_called`` attribute of the base class's member function,
regardless of the runtime destination of the call:

  .. code-block:: c++

    struct Foo { virtual void f(); };
    struct Bar : Foo {
      [[clang::not_tail_called]] void f() override;
    };
    void callera(Bar& bar) {
      Foo& foo = bar;
      // not_tail_called has no effect on here, even though the
      // underlying method is f from Bar.
      foo.f();
      bar.f(); // No tail-call optimization on here.
    }
  }];
}

def NoThrowDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the GNU style ``__attribute__((nothrow))`` and Microsoft style
``__declspec(nothrow)`` attribute as an equivalent of ``noexcept`` on function
declarations. This attribute informs the compiler that the annotated function
does not throw an exception. This prevents exception-unwinding. This attribute
is particularly useful on functions in the C Standard Library that are
guaranteed to not throw an exception.
    }];
}

def InternalLinkageDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``internal_linkage`` attribute changes the linkage type of the declaration
to internal. This is similar to C-style ``static``, but can be used on classes
and class methods. When applied to a class definition, this attribute affects
all methods and static data members of that class. This can be used to contain
the ABI of a C++ library by excluding unwanted class methods from the export
tables.
  }];
}

def ExcludeFromExplicitInstantiationDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``exclude_from_explicit_instantiation`` attribute opts-out a member of a
class template from being part of explicit template instantiations of that
class template. This means that an explicit instantiation will not instantiate
members of the class template marked with the attribute, but also that code
where an extern template declaration of the enclosing class template is visible
will not take for granted that an external instantiation of the class template
would provide those members (which would otherwise be a link error, since the
explicit instantiation won't provide those members). For example, let's say we
don't want the ``data()`` method to be part of libc++'s ABI. To make sure it
is not exported from the dylib, we give it hidden visibility:

  .. code-block:: c++

    // in <string>
    template <class CharT>
    class basic_string {
    public:
      __attribute__((__visibility__("hidden")))
      const value_type* data() const noexcept { ... }
    };

    template class basic_string<char>;

Since an explicit template instantiation declaration for ``basic_string<char>``
is provided, the compiler is free to assume that ``basic_string<char>::data()``
will be provided by another translation unit, and it is free to produce an
external call to this function. However, since ``data()`` has hidden visibility
and the explicit template instantiation is provided in a shared library (as
opposed to simply another translation unit), ``basic_string<char>::data()``
won't be found and a link error will ensue. This happens because the compiler
assumes that ``basic_string<char>::data()`` is part of the explicit template
instantiation declaration, when it really isn't. To tell the compiler that
``data()`` is not part of the explicit template instantiation declaration, the
``exclude_from_explicit_instantiation`` attribute can be used:

  .. code-block:: c++

    // in <string>
    template <class CharT>
    class basic_string {
    public:
      __attribute__((__visibility__("hidden")))
      __attribute__((exclude_from_explicit_instantiation))
      const value_type* data() const noexcept { ... }
    };

    template class basic_string<char>;

Now, the compiler won't assume that ``basic_string<char>::data()`` is provided
externally despite there being an explicit template instantiation declaration:
the compiler will implicitly instantiate ``basic_string<char>::data()`` in the
TUs where it is used.

This attribute can be used on static and non-static member functions of class
templates, static data members of class templates and member classes of class
templates.
  }];
}

def DisableTailCallsDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``disable_tail_calls`` attribute instructs the backend to not perform tail
call optimization inside the marked function.

For example:

  .. code-block:: c

    int callee(int);

    int foo(int a) __attribute__((disable_tail_calls)) {
      return callee(a); // This call is not tail-call optimized.
    }

Marking virtual functions as ``disable_tail_calls`` is legal.

  .. code-block:: c++

    int callee(int);

    class Base {
    public:
      [[clang::disable_tail_calls]] virtual int foo1() {
        return callee(); // This call is not tail-call optimized.
      }
    };

    class Derived1 : public Base {
    public:
      int foo1() override {
        return callee(); // This call is tail-call optimized.
      }
    };

  }];
}

def AnyX86NoCallerSavedRegistersDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use this attribute to indicate that the specified function has no
caller-saved registers. That is, all registers are callee-saved except for
registers used for passing parameters to the function or returning parameters
from the function.
The compiler saves and restores any modified registers that were not used for
passing or returning arguments to the function.

The user can call functions specified with the 'no_caller_saved_registers'
attribute from an interrupt handler without saving and restoring all
call-clobbered registers.

Note that 'no_caller_saved_registers' attribute is not a calling convention.
In fact, it only overrides the decision of which registers should be saved by
the caller, but not how the parameters are passed from the caller to the callee.

For example:

  .. code-block:: c

    __attribute__ ((no_caller_saved_registers, fastcall))
    void f (int arg1, int arg2) {
      ...
    }

  In this case parameters 'arg1' and 'arg2' will be passed in registers.
  In this case, on 32-bit x86 targets, the function 'f' will use ECX and EDX as
  register parameters. However, it will not assume any scratch registers and
  should save and restore any modified registers except for ECX and EDX.
  }];
}

def X86ForceAlignArgPointerDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use this attribute to force stack alignment.

Legacy x86 code uses 4-byte stack alignment. Newer aligned SSE instructions
(like 'movaps') that work with the stack require operands to be 16-byte aligned.
This attribute realigns the stack in the function prologue to make sure the
stack can be used with SSE instructions.

Note that the x86_64 ABI forces 16-byte stack alignment at the call site.
Because of this, 'force_align_arg_pointer' is not needed on x86_64, except in
rare cases where the caller does not align the stack properly (e.g. flow
jumps from i386 arch code).

  .. code-block:: c

    __attribute__ ((force_align_arg_pointer))
    void f () {
      ...
    }

  }];
}

def AnyX86NoCfCheckDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Jump Oriented Programming attacks rely on tampering with addresses used by
indirect call / jmp, e.g. redirect control-flow to non-programmer
intended bytes in the binary.
X86 Supports Indirect Branch Tracking (IBT) as part of Control-Flow
Enforcement Technology (CET). IBT instruments ENDBR instructions used to
specify valid targets of indirect call / jmp.
The ``nocf_check`` attribute has two roles:
1. Appertains to a function - do not add ENDBR instruction at the beginning of
the function.
2. Appertains to a function pointer - do not track the target function of this
pointer (by adding nocf_check prefix to the indirect-call instruction).
}];
}

def SwiftCallDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``swiftcall`` attribute indicates that a function should be called
using the Swift calling convention for a function or function pointer.

The lowering for the Swift calling convention, as described by the Swift
ABI documentation, occurs in multiple phases. The first, "high-level"
phase breaks down the formal parameters and results into innately direct
and indirect components, adds implicit parameters for the generic
signature, and assigns the context and error ABI treatments to parameters
where applicable. The second phase breaks down the direct parameters
and results from the first phase and assigns them to registers or the
stack. The ``swiftcall`` convention only handles this second phase of
lowering; the C function type must accurately reflect the results
of the first phase, as follows:

- Results classified as indirect by high-level lowering should be
  represented as parameters with the ``swift_indirect_result`` attribute.

- Results classified as direct by high-level lowering should be represented
  as follows:

  - First, remove any empty direct results.

  - If there are no direct results, the C result type should be ``void``.

  - If there is one direct result, the C result type should be a type with
    the exact layout of that result type.

  - If there are a multiple direct results, the C result type should be
    a struct type with the exact layout of a tuple of those results.

- Parameters classified as indirect by high-level lowering should be
  represented as parameters of pointer type.

- Parameters classified as direct by high-level lowering should be
  omitted if they are empty types; otherwise, they should be represented
  as a parameter type with a layout exactly matching the layout of the
  Swift parameter type.

- The context parameter, if present, should be represented as a trailing
  parameter with the ``swift_context`` attribute.

- The error result parameter, if present, should be represented as a
  trailing parameter (always following a context parameter) with the
  ``swift_error_result`` attribute.

``swiftcall`` does not support variadic arguments or unprototyped functions.

The parameter ABI treatment attributes are aspects of the function type.
A function type which applies an ABI treatment attribute to a
parameter is a different type from an otherwise-identical function type
that does not. A single parameter may not have multiple ABI treatment
attributes.

Support for this feature is target-dependent, although it should be
supported on every target that Swift supports. Query for this support
with ``__has_attribute(swiftcall)``. This implies support for the
``swift_context``, ``swift_error_result``, and ``swift_indirect_result``
attributes.
  }];
}

def SwiftContextDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``swift_context`` attribute marks a parameter of a ``swiftcall``
function as having the special context-parameter ABI treatment.

This treatment generally passes the context value in a special register
which is normally callee-preserved.

A ``swift_context`` parameter must either be the last parameter or must be
followed by a ``swift_error_result`` parameter (which itself must always be
the last parameter).

A context parameter must have pointer or reference type.
  }];
}

def SwiftErrorResultDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``swift_error_result`` attribute marks a parameter of a ``swiftcall``
function as having the special error-result ABI treatment.

This treatment generally passes the underlying error value in and out of
the function through a special register which is normally callee-preserved.
This is modeled in C by pretending that the register is addressable memory:

- The caller appears to pass the address of a variable of pointer type.
  The current value of this variable is copied into the register before
  the call; if the call returns normally, the value is copied back into the
  variable.

- The callee appears to receive the address of a variable. This address
  is actually a hidden location in its own stack, initialized with the
  value of the register upon entry. When the function returns normally,
  the value in that hidden location is written back to the register.

A ``swift_error_result`` parameter must be the last parameter, and it must be
preceded by a ``swift_context`` parameter.

A ``swift_error_result`` parameter must have type ``T**`` or ``T*&`` for some
type T. Note that no qualifiers are permitted on the intermediate level.

It is undefined behavior if the caller does not pass a pointer or
reference to a valid object.

The standard convention is that the error value itself (that is, the
value stored in the apparent argument) will be null upon function entry,
but this is not enforced by the ABI.
  }];
}

def SwiftIndirectResultDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall``
function as having the special indirect-result ABI treatment.

This treatment gives the parameter the target's normal indirect-result
ABI treatment, which may involve passing it differently from an ordinary
parameter. However, only the first indirect result will receive this
treatment. Furthermore, low-level lowering may decide that a direct result
must be returned indirectly; if so, this will take priority over the
``swift_indirect_result`` parameters.

A ``swift_indirect_result`` parameter must either be the first parameter or
follow another ``swift_indirect_result`` parameter.

A ``swift_indirect_result`` parameter must have type ``T*`` or ``T&`` for
some object type ``T``. If ``T`` is a complete type at the point of
definition of a function, it is undefined behavior if the argument
value does not point to storage of adequate size and alignment for a
value of type ``T``.

Making indirect results explicit in the signature allows C functions to
directly construct objects into them without relying on language
optimizations like C++'s named return value optimization (NRVO).
  }];
}

def SwiftAsyncDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_async";
  let Content = [{
The ``swift_async`` attribute specifies if and how a particular function or
Objective-C method is imported into a swift async method. For instance:

.. code-block:: objc

  @interface MyClass : NSObject
  -(void)notActuallyAsync:(int)p1 withCompletionHandler:(void (^)())handler
      __attribute__((swift_async(none)));

  -(void)actuallyAsync:(int)p1 callThisAsync:(void (^)())fun
      __attribute__((swift_async(swift_private, 1)));
  @end

Here, ``notActuallyAsync:withCompletionHandler`` would have been imported as
``async`` (because it's last parameter's selector piece is
``withCompletionHandler``) if not for the ``swift_async(none)`` attribute.
Conversely, ``actuallyAsync:callThisAsync`` wouldn't have been imported as
``async`` if not for the ``swift_async`` attribute because it doesn't match the
naming convention.

When using ``swift_async`` to enable importing, the first argument to the
attribute is either ``swift_private`` or ``not_swift_private`` to indicate
whether the function/method is private to the current framework, and the second
argument is the index of the completion handler parameter.
  }];
}

def SwiftAsyncErrorDocs : Documentation {
  let Category = SwiftDocs;
  let Heading = "swift_async_error";
  let Content = [{
The ``swift_async_error`` attribute specifies how an error state will be
represented in a swift async method. It's a bit analogous to the ``swift_error``
attribute for the generated async method. The ``swift_async_error`` attribute
can indicate a variety of different ways of representing an error.

- ``__attribute__((swift_async_error(zero_argument, N)))``, specifies that the
  async method is considered to have failed if the Nth argument to the
  completion handler is zero.

- ``__attribute__((swift_async_error(nonzero_argument, N)))``, specifies that
  the async method is considered to have failed if the Nth argument to the
  completion handler is non-zero.

- ``__attribute__((swift_async_error(nonnull_error)))``, specifies that the
  async method is considered to have failed if the ``NSError *`` argument to the
  completion handler is non-null.

- ``__attribute__((swift_async_error(none)))``, specifies that the async method
  cannot fail.


For instance:

.. code-block:: objc

  @interface MyClass : NSObject
  -(void)asyncMethod:(void (^)(char, int, float))handler
      __attribute__((swift_async(swift_private, 1)))
      __attribute__((swift_async_error(zero_argument, 2)));
  @end

Here, the ``swift_async`` attribute specifies that ``handler`` is the completion
handler for this method, and the ``swift_async_error`` attribute specifies that
the ``int`` parameter is the one that represents the error.
}];
}

def SuppressDocs : Documentation {
  let Category = DocCatStmt;
  let Content = [{
The ``[[gsl::suppress]]`` attribute suppresses specific
clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable
way. The attribute can be attached to declarations, statements, and at
namespace scope.

.. code-block:: c++

  [[gsl::suppress("Rh-public")]]
  void f_() {
    int *p;
    [[gsl::suppress("type")]] {
      p = reinterpret_cast<int*>(7);
    }
  }
  namespace N {
    [[clang::suppress("type", "bounds")]];
    ...
  }

.. _`C++ Core Guidelines`: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement
  }];
}

def AbiTagsDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``abi_tag`` attribute can be applied to a function, variable, class or
inline namespace declaration to modify the mangled name of the entity. It gives
the ability to distinguish between different versions of the same entity but
with different ABI versions supported. For example, a newer version of a class
could have a different set of data members and thus have a different size. Using
the ``abi_tag`` attribute, it is possible to have different mangled names for
a global variable of the class type. Therefore, the old code could keep using
the old mangled name and the new code will use the new mangled name with tags.
  }];
}

def PreferredNameDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``preferred_name`` attribute can be applied to a class template, and
specifies a preferred way of naming a specialization of the template. The
preferred name will be used whenever the corresponding template specialization
would otherwise be printed in a diagnostic or similar context.

The preferred name must be a typedef or type alias declaration that refers to a
specialization of the class template (not including any type qualifiers). In
general this requires the template to be declared at least twice. For example:

.. code-block:: c++

  template<typename T> struct basic_string;
  using string = basic_string<char>;
  using wstring = basic_string<wchar_t>;
  template<typename T> struct [[clang::preferred_name(string),
                                clang::preferred_name(wstring)]] basic_string {
    // ...
  };
  }];
}

def PreserveMostDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On X86-64 and AArch64 targets, this attribute changes the calling convention of
a function. The ``preserve_most`` calling convention attempts to make the code
in the caller as unintrusive as possible. This convention behaves identically
to the ``C`` calling convention on how arguments and return values are passed,
but it uses a different set of caller/callee-saved registers. This alleviates
the burden of saving and recovering a large register set before and after the
call in the caller. If the arguments are passed in callee-saved registers,
then they will be preserved by the callee across the call. This doesn't
apply for values returned in callee-saved registers.

- On X86-64 the callee preserves all general purpose registers, except for
  R11. R11 can be used as a scratch register. Floating-point registers
  (XMMs/YMMs) are not preserved and need to be saved by the caller.

The idea behind this convention is to support calls to runtime functions
that have a hot path and a cold path. The hot path is usually a small piece
of code that doesn't use many registers. The cold path might need to call out to
another function and therefore only needs to preserve the caller-saved
registers, which haven't already been saved by the caller. The
``preserve_most`` calling convention is very similar to the ``cold`` calling
convention in terms of caller/callee-saved registers, but they are used for
different types of function calls. ``coldcc`` is for function calls that are
rarely executed, whereas ``preserve_most`` function calls are intended to be
on the hot path and definitely executed a lot. Furthermore ``preserve_most``
doesn't prevent the inliner from inlining the function call.

This calling convention will be used by a future version of the Objective-C
runtime and should therefore still be considered experimental at this time.
Although this convention was created to optimize certain runtime calls to
the Objective-C runtime, it is not limited to this runtime and might be used
by other runtimes in the future too. The current implementation only
supports X86-64 and AArch64, but the intention is to support more architectures
in the future.
  }];
}

def PreserveAllDocs : Documentation {
  let Category = DocCatCallingConvs;
  let Content = [{
On X86-64 and AArch64 targets, this attribute changes the calling convention of
a function. The ``preserve_all`` calling convention attempts to make the code
in the caller even less intrusive than the ``preserve_most`` calling convention.
This calling convention also behaves identical to the ``C`` calling convention
on how arguments and return values are passed, but it uses a different set of
caller/callee-saved registers. This removes the burden of saving and
recovering a large register set before and after the call in the caller. If
the arguments are passed in callee-saved registers, then they will be
preserved by the callee across the call. This doesn't apply for values
returned in callee-saved registers.

- On X86-64 the callee preserves all general purpose registers, except for
  R11. R11 can be used as a scratch register. Furthermore it also preserves
  all floating-point registers (XMMs/YMMs).

The idea behind this convention is to support calls to runtime functions
that don't need to call out to any other functions.

This calling convention, like the ``preserve_most`` calling convention, will be
used by a future version of the Objective-C runtime and should be considered
experimental at this time.
  }];
}

def DeprecatedDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``deprecated`` attribute can be applied to a function, a variable, or a
type. This is useful when identifying functions, variables, or types that are
expected to be removed in a future version of a program.

Consider the function declaration for a hypothetical function ``f``:

.. code-block:: c++

  void f(void) __attribute__((deprecated("message", "replacement")));

When spelled as ``__attribute__((deprecated))``, the deprecated attribute can have
two optional string arguments. The first one is the message to display when
emitting the warning; the second one enables the compiler to provide a Fix-It
to replace the deprecated name with a new name. Otherwise, when spelled as
``[[gnu::deprecated]]`` or ``[[deprecated]]``, the attribute can have one optional
string argument which is the message to display when emitting the warning.
  }];
}

def IFuncDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
``__attribute__((ifunc("resolver")))`` is used to mark that the address of a
declaration should be resolved at runtime by calling a resolver function.

The symbol name of the resolver function is given in quotes. A function with
this name (after mangling) must be defined in the current translation unit; it
may be ``static``. The resolver function should return a pointer.

The ``ifunc`` attribute may only be used on a function declaration. A function
declaration with an ``ifunc`` attribute is considered to be a definition of the
declared entity. The entity must not have weak linkage; for example, in C++,
it cannot be applied to a declaration if a definition at that location would be
considered inline.

Not all targets support this attribute. ELF target support depends on both the
linker and runtime linker, and is available in at least lld 4.0 and later,
binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
Non-ELF targets currently do not support this attribute.
  }];
}

def LTOVisibilityDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
See :doc:`LTOVisibility`.
  }];
}

def RenderScriptKernelAttributeDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
``__attribute__((kernel))`` is used to mark a ``kernel`` function in
RenderScript.

In RenderScript, ``kernel`` functions are used to express data-parallel
computations. The RenderScript runtime efficiently parallelizes ``kernel``
functions to run on computational resources such as multi-core CPUs and GPUs.
See the RenderScript_ documentation for more information.

.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html
  }];
}

def XRayDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "xray_always_instrument, xray_never_instrument, xray_log_args";
  let Content = [{
``__attribute__((xray_always_instrument))`` or
``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++),
methods (in Objective C), and free functions (in C, C++, and Objective C) to be
instrumented with XRay. This will cause the function to always have space at
the beginning and exit points to allow for runtime patching.

Conversely, ``__attribute__((xray_never_instrument))`` or
``[[clang::xray_never_instrument]]`` will inhibit the insertion of these
instrumentation points.

If a function has neither of these attributes, they become subject to the XRay
heuristics used to determine whether a function should be instrumented or
otherwise.

``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is
used to preserve N function arguments for the logging function. Currently,
only N==1 is supported.
  }];
}

def PatchableFunctionEntryDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
``__attribute__((patchable_function_entry(N,M)))`` is used to generate M NOPs
before the function entry and N-M NOPs after the function entry. This attribute
takes precedence over the command line option ``-fpatchable-function-entry=N,M``.
``M`` defaults to 0 if omitted.

This attribute is only supported on
aarch64/aarch64-be/riscv32/riscv64/i386/x86-64 targets.
}];
}

def TransparentUnionDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute can be applied to a union to change the behavior of calls to
functions that have an argument with a transparent union type. The compiler
behavior is changed in the following manner:

- A value whose type is any member of the transparent union can be passed as an
  argument without the need to cast that value.

- The argument is passed to the function using the calling convention of the
  first member of the transparent union. Consequently, all the members of the
  transparent union should have the same calling convention as its first member.

Transparent unions are not supported in C++.
  }];
}

def ObjCSubclassingRestrictedDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute can be added to an Objective-C ``@interface`` declaration to
ensure that this class cannot be subclassed.
  }];
}

def ObjCNonLazyClassDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute can be added to an Objective-C ``@interface`` or
``@implementation`` declaration to add the class to the list of non-lazily
initialized classes. A non-lazy class will be initialized eagerly when the
Objective-C runtime is loaded. This is required for certain system classes which
have instances allocated in non-standard ways, such as the classes for blocks
and constant strings. Adding this attribute is essentially equivalent to
providing a trivial ``+load`` method but avoids the (fairly small) load-time
overheads associated with defining and calling such a method.
  }];
}

def ObjCDirectDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``objc_direct`` attribute can be used to mark an Objective-C method as
being *direct*. A direct method is treated statically like an ordinary method,
but dynamically it behaves more like a C function. This lowers some of the costs
associated with the method but also sacrifices some of the ordinary capabilities
of Objective-C methods.

A message send of a direct method calls the implementation directly, as if it
were a C function, rather than using ordinary Objective-C method dispatch. This
is substantially faster and potentially allows the implementation to be inlined,
but it also means the method cannot be overridden in subclasses or replaced
dynamically, as ordinary Objective-C methods can.

Furthermore, a direct method is not listed in the class's method lists. This
substantially reduces the code-size overhead of the method but also means it
cannot be called dynamically using ordinary Objective-C method dispatch at all;
in particular, this means that it cannot override a superclass method or satisfy
a protocol requirement.

Because a direct method cannot be overridden, it is an error to perform
a ``super`` message send of one.

Although a message send of a direct method causes the method to be called
directly as if it were a C function, it still obeys Objective-C semantics in other
ways:

- If the receiver is ``nil``, the message send does nothing and returns the zero value
  for the return type.

- A message send of a direct class method will cause the class to be initialized,
  including calling the ``+initialize`` method if present.

- The implicit ``_cmd`` parameter containing the method's selector is still defined.
  In order to minimize code-size costs, the implementation will not emit a reference
  to the selector if the parameter is unused within the method.

Symbols for direct method implementations are implicitly given hidden
visibility, meaning that they can only be called within the same linkage unit.

It is an error to do any of the following:

- declare a direct method in a protocol,
- declare an override of a direct method with a method in a subclass,
- declare an override of a non-direct method with a direct method in a subclass,
- declare a method with different directness in different class interfaces, or
- implement a non-direct method (as declared in any class interface) with a direct method.

If any of these rules would be violated if every method defined in an
``@implementation`` within a single linkage unit were declared in an
appropriate class interface, the program is ill-formed with no diagnostic
required. If a violation of this rule is not diagnosed, behavior remains
well-defined; this paragraph is simply reserving the right to diagnose such
conflicts in the future, not to treat them as undefined behavior.

Additionally, Clang will warn about any ``@selector`` expression that
names a selector that is only known to be used for direct methods.

For the purpose of these rules, a "class interface" includes a class's primary
``@interface`` block, its class extensions, its categories, its declared protocols,
and all the class interfaces of its superclasses.

An Objective-C property can be declared with the ``direct`` property
attribute. If a direct property declaration causes an implicit declaration of
a getter or setter method (that is, if the given method is not explicitly
declared elsewhere), the method is declared to be direct.

Some programmers may wish to make many methods direct at once. In order
to simplify this, the ``objc_direct_members`` attribute is provided; see its
documentation for more information.
  }];
}

def ObjCDirectMembersDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``objc_direct_members`` attribute can be placed on an Objective-C
``@interface`` or ``@implementation`` to mark that methods declared
therein should be considered direct by default. See the documentation
for ``objc_direct`` for more information about direct methods.

When ``objc_direct_members`` is placed on an ``@interface`` block, every
method in the block is considered to be declared as direct. This includes any
implicit method declarations introduced by property declarations. If the method
redeclares a non-direct method, the declaration is ill-formed, exactly as if the
method was annotated with the ``objc_direct`` attribute.

When ``objc_direct_members`` is placed on an ``@implementation`` block,
methods defined in the block are considered to be declared as direct unless
they have been previously declared as non-direct in any interface of the class.
This includes the implicit method definitions introduced by synthesized
properties, including auto-synthesized properties.
  }];
}

def ObjCNonRuntimeProtocolDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``objc_non_runtime_protocol`` attribute can be used to mark that an
Objective-C protocol is only used during static type-checking and doesn't need
to be represented dynamically. This avoids several small code-size and run-time
overheads associated with handling the protocol's metadata. A non-runtime
protocol cannot be used as the operand of a ``@protocol`` expression, and
dynamic attempts to find it with ``objc_getProtocol`` will fail.

If a non-runtime protocol inherits from any ordinary protocols, classes and
derived protocols that declare conformance to the non-runtime protocol will
dynamically list their conformance to those bare protocols.
  }];
}

def SelectAnyDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
This attribute appertains to a global symbol, causing it to have a weak
definition (
`linkonce <https://llvm.org/docs/LangRef.html#linkage-types>`_
), allowing the linker to select any definition.

For more information see
`gcc documentation <https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Microsoft-Windows-Variable-Attributes.html>`_
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
}]; }

def WebAssemblyExportNameDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((export_name(<name>)))``
attribute for the WebAssembly target. This attribute may be attached to a
function declaration, where it modifies how the symbol is to be exported
from the linked WebAssembly.

WebAssembly functions are exported via string name. By default when a symbol
is exported, the export name for C/C++ symbols are the same as their C/C++
symbol names. This attribute can be used to override the default behavior, and
request a specific string name be used instead.
  }];
}

def WebAssemblyImportModuleDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((import_module(<module_name>)))``
attribute for the WebAssembly target. This attribute may be attached to a
function declaration, where it modifies how the symbol is to be imported
within the WebAssembly linking environment.

WebAssembly imports use a two-level namespace scheme, consisting of a module
name, which typically identifies a module from which to import, and a field
name, which typically identifies a field from that module to import. By
default, module names for C/C++ symbols are assigned automatically by the
linker. This attribute can be used to override the default behavior, and
request a specific module name be used instead.
  }];
}

def WebAssemblyImportNameDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((import_name(<name>)))``
attribute for the WebAssembly target. This attribute may be attached to a
function declaration, where it modifies how the symbol is to be imported
within the WebAssembly linking environment.

WebAssembly imports use a two-level namespace scheme, consisting of a module
name, which typically identifies a module from which to import, and a field
name, which typically identifies a field from that module to import. By
default, field names for C/C++ symbols are the same as their C/C++ symbol
names. This attribute can be used to override the default behavior, and
request a specific field name be used instead.
  }];
}

def ArtificialDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``artificial`` attribute can be applied to an inline function. If such a
function is inlined, the attribute indicates that debuggers should associate
the resulting instructions with the call site, rather than with the
corresponding line within the inlined callee.
  }];
}

def NoDerefDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``noderef`` attribute causes clang to diagnose dereferences of annotated pointer types.
This is ideally used with pointers that point to special memory which cannot be read
from or written to, but allowing for the pointer to be used in pointer arithmetic.
The following are examples of valid expressions where dereferences are diagnosed:

.. code-block:: c

  int __attribute__((noderef)) *p;
  int x = *p;  // warning

  int __attribute__((noderef)) **p2;
  x = **p2;  // warning

  int * __attribute__((noderef)) *p3;
  p = *p3;  // warning

  struct S {
    int a;
  };
  struct S __attribute__((noderef)) *s;
  x = s->a;    // warning
  x = (*s).a;  // warning

Not all dereferences may diagnose a warning if the value directed by the pointer may not be
accessed. The following are examples of valid expressions where may not be diagnosed:

.. code-block:: c

  int *q;
  int __attribute__((noderef)) *p;
  q = &*p;
  q = *&p;

  struct S {
    int a;
  };
  struct S __attribute__((noderef)) *s;
  p = &s->a;
  p = &(*s).a;

``noderef`` is currently only supported for pointers and arrays and not usable
for references or Objective-C object pointers.

.. code-block: c++

  int x = 2;
  int __attribute__((noderef)) &y = x;  // warning: 'noderef' can only be used on an array or pointer type

.. code-block: objc

  id __attribute__((noderef)) obj = [NSObject new]; // warning: 'noderef' can only be used on an array or pointer type
}];
}

def ReinitializesDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``reinitializes`` attribute can be applied to a non-static, non-const C++
member function to indicate that this member function reinitializes the entire
object to a known state, independent of the previous state of the object.

This attribute can be interpreted by static analyzers that warn about uses of an
object that has been left in an indeterminate state by a move operation. If a
member function marked with the ``reinitializes`` attribute is called on a
moved-from object, the analyzer can conclude that the object is no longer in an
indeterminate state.

A typical example where this attribute would be used is on functions that clear
a container class:

.. code-block:: c++

  template <class T>
  class Container {
  public:
    ...
    [[clang::reinitializes]] void Clear();
    ...
  };
  }];
}

def AlwaysDestroyDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``always_destroy`` attribute specifies that a variable with static or thread
storage duration should have its exit-time destructor run. This attribute is the
default unless clang was invoked with -fno-c++-static-destructors.
  }];
}

def NoDestroyDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``no_destroy`` attribute specifies that a variable with static or thread
storage duration shouldn't have its exit-time destructor run. Annotating every
static and thread duration variable with this attribute is equivalent to
invoking clang with -fno-c++-static-destructors.

If a variable is declared with this attribute, clang doesn't access check or
generate the type's destructor. If you have a type that you only want to be
annotated with ``no_destroy``, you can therefore declare the destructor private:

.. code-block:: c++

  struct only_no_destroy {
    only_no_destroy();
  private:
    ~only_no_destroy();
  };

  [[clang::no_destroy]] only_no_destroy global; // fine!

Note that destructors are still required for subobjects of aggregates annotated
with this attribute. This is because previously constructed subobjects need to
be destroyed if an exception gets thrown before the initialization of the
complete object is complete. For instance:

.. code-block:: c++

  void f() {
    try {
      [[clang::no_destroy]]
      static only_no_destroy array[10]; // error, only_no_destroy has a private destructor.
    } catch (...) {
      // Handle the error
    }
  }

Here, if the construction of ``array[9]`` fails with an exception, ``array[0..8]``
will be destroyed, so the element's destructor needs to be accessible.
  }];
}

def UninitializedDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The command-line parameter ``-ftrivial-auto-var-init=*`` can be used to
initialize trivial automatic stack variables. By default, trivial automatic
stack variables are uninitialized. This attribute is used to override the
command-line parameter, forcing variables to remain uninitialized. It has no
semantic meaning in that using uninitialized values is undefined behavior,
it rather documents the programmer's intent.
  }];
}

def LoaderUninitializedDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``loader_uninitialized`` attribute can be placed on global variables to
indicate that the variable does not need to be zero initialized by the loader.
On most targets, zero-initialization does not incur any additional cost.
For example, most general purpose operating systems deliberately ensure
that all memory is properly initialized in order to avoid leaking privileged
information from the kernel or other programs. However, some targets
do not make this guarantee, and on these targets, avoiding an unnecessary
zero-initialization can have a significant impact on load times and/or code
size.

A declaration with this attribute is a non-tentative definition just as if it
provided an initializer. Variables with this attribute are considered to be
uninitialized in the same sense as a local variable, and the programs must
write to them before reading from them. If the variable's type is a C++ class
type with a non-trivial default constructor, or an array thereof, this attribute
only suppresses the static zero-initialization of the variable, not the dynamic
initialization provided by executing the default constructor.
  }];
}

def CallbackDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``callback`` attribute specifies that the annotated function may invoke the
specified callback zero or more times. The callback, as well as the passed
arguments, are identified by their parameter name or position (starting with
1!) in the annotated function. The first position in the attribute identifies
the callback callee, the following positions declare describe its arguments.
The callback callee is required to be callable with the number, and order, of
the specified arguments. The index ``0``, or the identifier ``this``, is used to
represent an implicit "this" pointer in class methods. If there is no implicit
"this" pointer it shall not be referenced. The index '-1', or the name "__",
represents an unknown callback callee argument. This can be a value which is
not present in the declared parameter list, or one that is, but is potentially
inspected, captured, or modified. Parameter names and indices can be mixed in
the callback attribute.

The ``callback`` attribute, which is directly translated to ``callback``
metadata <http://llvm.org/docs/LangRef.html#callback-metadata>, make the
connection between the call to the annotated function and the callback callee.
This can enable interprocedural optimizations which were otherwise impossible.
If a function parameter is mentioned in the ``callback`` attribute, through its
position, it is undefined if that parameter is used for anything other than the
actual callback. Inspected, captured, or modified parameters shall not be
listed in the ``callback`` metadata.

Example encodings for the callback performed by ``pthread_create`` are shown
below. The explicit attribute annotation indicates that the third parameter
(``start_routine``) is called zero or more times by the ``pthread_create`` function,
and that the fourth parameter (``arg``) is passed along. Note that the callback
behavior of ``pthread_create`` is automatically recognized by Clang. In addition,
the declarations of ``__kmpc_fork_teams`` and ``__kmpc_fork_call``, generated for
``#pragma omp target teams`` and ``#pragma omp parallel``, respectively, are also
automatically recognized as broker functions. Further functions might be added
in the future.

  .. code-block:: c

    __attribute__((callback (start_routine, arg)))
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                       void *(*start_routine) (void *), void *arg);

    __attribute__((callback (3, 4)))
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                       void *(*start_routine) (void *), void *arg);

  }];
}

def CalledOnceDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``called_once`` attribute specifies that the annotated function or method
parameter is invoked exactly once on all execution paths. It only applies
to parameters with function-like types, i.e. function pointers or blocks. This
concept is particularly useful for asynchronous programs.

Clang implements a check for ``called_once`` parameters,
``-Wcalled-once-parameter``. It is on by default and finds the following
violations:

* Parameter is not called at all.

* Parameter is called more than once.

* Parameter is not called on one of the execution paths.

In the latter case, Clang pinpoints the path where parameter is not invoked
by showing the control-flow statement where the path diverges.

.. code-block:: objc

  void fooWithCallback(void (^callback)(void) __attribute__((called_once))) {
    if (somePredicate()) {
      ...
      callback();
    } esle {
      callback(); // OK: callback is called on every path
    }
  }

  void barWithCallback(void (^callback)(void) __attribute__((called_once))) {
    if (somePredicate()) {
      ...
      callback(); // note: previous call is here
    }
    callback(); // warning: callback is called twice
  }

  void foobarWithCallback(void (^callback)(void) __attribute__((called_once))) {
    if (somePredicate()) {  // warning: callback is not called when condition is false
      ...
      callback();
    }
  }

This attribute is useful for API developers who want to double-check if they
implemented their method correctly.

  }];
}

def GnuInlineDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline
semantics, meaning:

* If any declaration that is declared ``inline`` is not declared ``extern``,
  then the ``inline`` keyword is just a hint. In particular, an out-of-line
  definition is still emitted for a function with external linkage, even if all
  call sites are inlined, unlike in C99 and C++ inline semantics.

* If all declarations that are declared ``inline`` are also declared
  ``extern``, then the function body is present only for inlining and no
  out-of-line version is emitted.

Some important consequences: ``static inline`` emits an out-of-line
version if needed, a plain ``inline`` definition emits an out-of-line version
always, and an ``extern inline`` definition (in a header) followed by a
(non-``extern``) ``inline`` declaration in a source file emits an out-of-line
version of the function in that source file but provides the function body for
inlining to all includers of the header.

Either ``__GNUC_GNU_INLINE__`` (GNU inline semantics) or
``__GNUC_STDC_INLINE__`` (C99 semantics) will be defined (they are mutually
exclusive). If ``__GNUC_STDC_INLINE__`` is defined, then the ``gnu_inline``
function attribute can be used to get GNU inline semantics on a per function
basis. If ``__GNUC_GNU_INLINE__`` is defined, then the translation unit is
already being compiled with GNU inline semantics as the implied default. It is
unspecified which macro is defined in a C++ compilation.

GNU inline semantics are the default behavior with ``-std=gnu89``,
``-std=c89``, ``-std=c94``, or ``-fgnu89-inline``.
  }];
}

def SpeculativeLoadHardeningDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
  This attribute can be applied to a function declaration in order to indicate
  that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
  should be enabled for the function body. This can also be applied to a method
  in Objective C. This attribute will take precedence over the command line flag in
  the case where `-mno-speculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified.

  Speculative Load Hardening is a best-effort mitigation against
  information leak attacks that make use of control flow
  miss-speculation - specifically miss-speculation of whether a branch
  is taken or not. Typically vulnerabilities enabling such attacks are
  classified as "Spectre variant #1". Notably, this does not attempt to
  mitigate against miss-speculation of branch target, classified as
  "Spectre variant #2" vulnerabilities.

  When inlining, the attribute is sticky. Inlining a function that
  carries this attribute will cause the caller to gain the
  attribute. This is intended to provide a maximally conservative model
  where the code in a function annotated with this attribute will always
  (even after inlining) end up hardened.
  }];
}

def NoSpeculativeLoadHardeningDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
  This attribute can be applied to a function declaration in order to indicate
  that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
  is *not* needed for the function body. This can also be applied to a method
  in Objective C. This attribute will take precedence over the command line flag in
  the case where `-mspeculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified.

  Warning: This attribute may not prevent Speculative Load Hardening from being
  enabled for a function which inlines a function that has the
  'speculative_load_hardening' attribute. This is intended to provide a
  maximally conservative model where the code that is marked with the
  'speculative_load_hardening' attribute will always (even when inlined)
  be hardened. A user of this attribute may want to mark functions called by
  a function they do not want to be hardened with the 'noinline' attribute.

  For example:

  .. code-block:: c

    __attribute__((speculative_load_hardening))
    int foo(int i) {
      return i;
    }

    // Note: bar() may still have speculative load hardening enabled if
    // foo() is inlined into bar(). Mark foo() with __attribute__((noinline))
    // to avoid this situation.
    __attribute__((no_speculative_load_hardening))
    int bar(int i) {
      return foo(i);
    }
  }];
}

def ObjCExternallyRetainedDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``objc_externally_retained`` attribute can be applied to strong local
variables, functions, methods, or blocks to opt into
`externally-retained semantics
<https://clang.llvm.org/docs/AutomaticReferenceCounting.html#externally-retained-variables>`_.

When applied to the definition of a function, method, or block, every parameter
of the function with implicit strong retainable object pointer type is
considered externally-retained, and becomes ``const``. By explicitly annotating
a parameter with ``__strong``, you can opt back into the default
non-externally-retained behavior for that parameter. For instance,
``first_param`` is externally-retained below, but not ``second_param``:

.. code-block:: objc

  __attribute__((objc_externally_retained))
  void f(NSArray *first_param, __strong NSArray *second_param) {
    // ...
  }

Likewise, when applied to a strong local variable, that variable becomes
``const`` and is considered externally-retained.

When compiled without ``-fobjc-arc``, this attribute is ignored.
}]; }

def MIGConventionDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
  The Mach Interface Generator release-on-success convention dictates
functions that follow it to only release arguments passed to them when they
return "success" (a ``kern_return_t`` error code that indicates that
no errors have occurred). Otherwise the release is performed by the MIG client
that called the function. The annotation ``__attribute__((mig_server_routine))``
is applied in order to specify which functions are expected to follow the
convention. This allows the Static Analyzer to find bugs caused by violations of
that convention. The attribute would normally appear on the forward declaration
of the actual server routine in the MIG server header, but it may also be
added to arbitrary functions that need to follow the same convention - for
example, a user can add them to auxiliary functions called by the server routine
that have their return value of type ``kern_return_t`` unconditionally returned
from the routine. The attribute can be applied to C++ methods, and in this case
it will be automatically applied to overrides if the method is virtual. The
attribute can also be written using C++11 syntax: ``[[mig::server_routine]]``.
}];
}

def MSAllocatorDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
The ``__declspec(allocator)`` attribute is applied to functions that allocate
memory, such as operator new in C++. When CodeView debug information is emitted
(enabled by ``clang -gcodeview`` or ``clang-cl /Z7``), Clang will attempt to
record the code offset of heap allocation call sites in the debug info. It will
also record the type being allocated using some local heuristics. The Visual
Studio debugger uses this information to `profile memory usage`_.

.. _profile memory usage: https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage

This attribute does not affect optimizations in any way, unlike GCC's
``__attribute__((malloc))``.
}];
}

def CFGuardDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Code can indicate CFG checks are not wanted with the ``__declspec(guard(nocf))``
attribute. This directs the compiler to not insert any CFG checks for the entire
function. This approach is typically used only sparingly in specific situations 
where the programmer has manually inserted "CFG-equivalent" protection. The 
programmer knows that they are calling through some read-only function table 
whose address is obtained through read-only memory references and for which the 
index is masked to the function table limit. This approach may also be applied 
to small wrapper functions that are not inlined and that do nothing more than 
make a call through a function pointer. Since incorrect usage of this directive 
can compromise the security of CFG, the programmer must be very careful using 
the directive. Typically, this usage is limited to very small functions that 
only call one function.

`Control Flow Guard documentation <https://docs.microsoft.com/en-us/windows/win32/secbp/pe-metadata>`
}];
}

def CUDADeviceBuiltinSurfaceTypeDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``device_builtin_surface_type`` attribute can be applied to a class
template when declaring the surface reference. A surface reference variable
could be accessed on the host side and, on the device side, might be translated
into an internal surface object, which is established through surface bind and
unbind runtime APIs.
  }];
}

def CUDADeviceBuiltinTextureTypeDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``device_builtin_texture_type`` attribute can be applied to a class
template when declaring the texture reference. A texture reference variable
could be accessed on the host side and, on the device side, might be translated
into an internal texture object, which is established through texture bind and
unbind runtime APIs.
  }];
}

def HIPManagedAttrDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``__managed__`` attribute can be applied to a global variable declaration in HIP.
A managed variable is emitted as an undefined global symbol in the device binary and is
registered by ``__hipRegisterManagedVariable`` in init functions. The HIP runtime allocates
managed memory and uses it to define the symbol when loading the device binary.
A managed variable can be accessed in both device and host code.
  }];
}

def LifetimeOwnerDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
.. Note:: This attribute is experimental and its effect on analysis is subject to change in
  a future version of clang.

The attribute ``[[gsl::Owner(T)]]`` applies to structs and classes that own an
object of type ``T``:

.. code::

  class [[gsl::Owner(int)]] IntOwner {
  private:
    int value;
  public:
    int *getInt() { return &value; }
  };

The argument ``T`` is optional and is ignored.
This attribute may be used by analysis tools and has no effect on code
generation. A ``void`` argument means that the class can own any type.

See Pointer_ for an example.
}];
}

def LifetimePointerDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
.. Note:: This attribute is experimental and its effect on analysis is subject to change in
  a future version of clang.

The attribute ``[[gsl::Pointer(T)]]`` applies to structs and classes that behave
like pointers to an object of type ``T``:

.. code::

  class [[gsl::Pointer(int)]] IntPointer {
  private:
    int *valuePointer;
  public:
    int *getInt() { return &valuePointer; }
  };

The argument ``T`` is optional and is ignored.
This attribute may be used by analysis tools and has no effect on code
generation. A ``void`` argument means that the pointer can point to any type.

Example:
When constructing an instance of a class annotated like this (a Pointer) from
an instance of a class annotated with ``[[gsl::Owner]]`` (an Owner),
then the analysis will consider the Pointer to point inside the Owner.
When the Owner's lifetime ends, it will consider the Pointer to be dangling.

.. code-block:: c++

  int f() {
    IntPointer P;
    if (true) {
      IntOwner O(7);
      P = IntPointer(O); // P "points into" O
    } // P is dangling
    return P.get(); // error: Using a dangling Pointer.
  }

}];
}

def ArmBuiltinAliasDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
This attribute is used in the implementation of the ACLE intrinsics.
It allows the intrinsic functions to
be declared using the names defined in ACLE, and still be recognized
as clang builtins equivalent to the underlying name. For example,
``arm_mve.h`` declares the function ``vaddq_u32`` with
``__attribute__((__clang_arm_mve_alias(__builtin_arm_mve_vaddq_u32)))``,
and similarly, one of the type-overloaded declarations of ``vaddq``
will have the same attribute. This ensures that both functions are
recognized as that clang builtin, and in the latter case, the choice
of which builtin to identify the function as can be deferred until
after overload resolution.

This attribute can only be used to set up the aliases for certain Arm
intrinsic functions; it is intended for use only inside ``arm_*.h``
and is not a general mechanism for declaring arbitrary aliases for
clang builtin functions.
  }];
}

def NoBuiltinDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
.. Note:: This attribute is not yet fully implemented, it is validated but has
          no effect on the generated code.

The ``__attribute__((no_builtin))`` is similar to the ``-fno-builtin`` flag
except it is specific to the body of a function. The attribute may also be
applied to a virtual function but has no effect on the behavior of overriding
functions in a derived class.

It accepts one or more strings corresponding to the specific names of the
builtins to disable (e.g. "memcpy", "memset").
If the attribute is used without parameters it will disable all buitins at
once.

.. code-block:: c++

  // The compiler is not allowed to add any builtin to foo's body.
  void foo(char* data, size_t count) __attribute__((no_builtin)) {
    // The compiler is not allowed to convert the loop into
    // `__builtin_memset(data, 0xFE, count);`.
    for (size_t i = 0; i < count; ++i)
      data[i] = 0xFE;
  }

  // The compiler is not allowed to add the `memcpy` builtin to bar's body.
  void bar(char* data, size_t count) __attribute__((no_builtin("memcpy"))) {
    // The compiler is allowed to convert the loop into
    // `__builtin_memset(data, 0xFE, count);` but cannot generate any
    // `__builtin_memcpy`
    for (size_t i = 0; i < count; ++i)
      data[i] = 0xFE;
  }
  }];
}

def HandleDocs : DocumentationCategory<"Handle Attributes"> {
  let Content = [{
Handles are a way to identify resources like files, sockets, and processes.
They are more opaque than pointers and widely used in system programming. They
have similar risks such as never releasing a resource associated with a handle,
attempting to use a handle that was already released, or trying to release a
handle twice. Using the annotations below it is possible to make the ownership
of the handles clear: whose responsibility is to release them. They can also
aid static analysis tools to find bugs.
  }];
}

def AcquireHandleDocs : Documentation {
  let Category = HandleDocs;
  let Content = [{
If this annotation is on a function or a function type it is assumed to return
a new handle. In case this annotation is on an output parameter,
the function is assumed to fill the corresponding argument with a new
handle.

.. code-block:: c++

  // Output arguments from Zircon.
  zx_status_t zx_socket_create(uint32_t options,
                               zx_handle_t __attribute__((acquire_handle)) * out0,
                               zx_handle_t* out1 [[clang::acquire_handle]]);


  // Returned handle.
  [[clang::acquire_handle]] int open(const char *path, int oflag, ... );
  int open(const char *path, int oflag, ... ) __attribute__((acquire_handle));
  }];
}

def UseHandleDocs : Documentation {
  let Category = HandleDocs;
  let Content = [{
A function taking a handle by value might close the handle. If a function
parameter is annotated with ``use_handle`` it is assumed to not to change
the state of the handle. It is also assumed to require an open handle to work with.

.. code-block:: c++

  zx_status_t zx_port_wait(zx_handle_t handle [[clang::use_handle]],
                           zx_time_t deadline,
                           zx_port_packet_t* packet);
  }];
}

def ReleaseHandleDocs : Documentation {
  let Category = HandleDocs;
  let Content = [{
If a function parameter is annotated with ``release_handle`` it is assumed to
close the handle. It is also assumed to require an open handle to work with.

.. code-block:: c++

  zx_status_t zx_handle_close(zx_handle_t handle [[clang::release_handle]]);
  }];
}

def ArmSveVectorBitsDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``arm_sve_vector_bits(N)`` attribute is defined by the Arm C Language
Extensions (ACLE) for SVE. It is used to define fixed-length (VLST) variants of
sizeless types (VLAT).

For example:

.. code-block:: c

  #include <arm_sve.h>

  #if __ARM_FEATURE_SVE_BITS==512
  typedef svint32_t fixed_svint32_t __attribute__((arm_sve_vector_bits(512)));
  #endif

Creates a type ``fixed_svint32_t`` that is a fixed-length variant of
``svint32_t`` that contains exactly 512-bits. Unlike ``svint32_t``, this type
can be used in globals, structs, unions, and arrays, all of which are
unsupported for sizeless types.

The attribute can be attached to a single SVE vector (such as ``svint32_t``) or
to the SVE predicate type ``svbool_t``, this excludes tuple types such as
``svint32x4_t``. The behavior of the attribute is undefined unless
``N==__ARM_FEATURE_SVE_BITS``, the implementation defined feature macro that is
enabled under the ``-msve-vector-bits`` flag.

For more information See `Arm C Language Extensions for SVE
<https://developer.arm.com/documentation/100987/latest>`_ for more information.
}];
}

def ArmMveStrictPolymorphismDocs : Documentation {
    let Category = DocCatType;
    let Content = [{
This attribute is used in the implementation of the ACLE intrinsics for the Arm
MVE instruction set. It is used to define the vector types used by the MVE
intrinsics.

Its effect is to modify the behavior of a vector type with respect to function
overloading. If a candidate function for overload resolution has a parameter
type with this attribute, then the selection of that candidate function will be
disallowed if the actual argument can only be converted via a lax vector
conversion. The aim is to prevent spurious ambiguity in ARM MVE polymorphic
intrinsics.

.. code-block:: c++

  void overloaded(uint16x8_t vector, uint16_t scalar);
  void overloaded(int32x4_t vector, int32_t scalar);
  uint16x8_t myVector;
  uint16_t myScalar;

  // myScalar is promoted to int32_t as a side effect of the addition,
  // so if lax vector conversions are considered for myVector, then
  // the two overloads are equally good (one argument conversion
  // each). But if the vector has the __clang_arm_mve_strict_polymorphism
  // attribute, only the uint16x8_t,uint16_t overload will match.
  overloaded(myVector, myScalar + 1);

However, this attribute does not prohibit lax vector conversions in contexts
other than overloading.

.. code-block:: c++

  uint16x8_t function();

  // This is still permitted with lax vector conversion enabled, even
  // if the vector types have __clang_arm_mve_strict_polymorphism
  int32x4_t result = function();

    }];
}

def ArmCmseNSCallDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
This attribute declares a non-secure function type. When compiling for secure
state, a call to such a function would switch from secure to non-secure state.
All non-secure function calls must happen only through a function pointer, and
a non-secure function type should only be used as a base type of a pointer.
See `ARMv8-M Security Extensions: Requirements on Development
Tools - Engineering Specification Documentation
<https://developer.arm.com/docs/ecm0359818/latest/>`_ for more information.
  }];
}

def ArmCmseNSEntryDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
This attribute declares a function that can be called from non-secure state, or
from secure state. Entering from and returning to non-secure state would switch
to and from secure state, respectively, and prevent flow of information
to non-secure state, except via return values. See `ARMv8-M Security Extensions:
Requirements on Development Tools - Engineering Specification Documentation
<https://developer.arm.com/docs/ecm0359818/latest/>`_ for more information.
  }];
}

def AlwaysInlineDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Inlining heuristics are disabled and inlining is always attempted regardless of
optimization level.

Does not guarantee that inline substitution actually occurs.

See also `the Microsoft Docs on Inline Functions`_, `the GCC Common Function
Attribute docs`_, and `the GCC Inline docs`_.

.. _the Microsoft Docs on Inline Functions: https://docs.microsoft.com/en-us/cpp/cpp/inline-functions-cpp
.. _the GCC Common Function Attribute docs: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
.. _the GCC Inline docs: https://gcc.gnu.org/onlinedocs/gcc/Inline.html

}];
  let Heading = "always_inline, __force_inline";
}

def EnforceTCBDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
  The ``enforce_tcb`` attribute can be placed on functions to enforce that a
  trusted compute base (TCB) does not call out of the TCB. This generates a
  warning every time a function not marked with an ``enforce_tcb`` attribute is
  called from a function with the ``enforce_tcb`` attribute. A function may be a
  part of multiple TCBs. Invocations through function pointers are currently
  not checked. Builtins are considered to a part of every TCB.

  - ``enforce_tcb(Name)`` indicates that this function is a part of the TCB named ``Name``
  }];
}

def EnforceTCBLeafDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
  The ``enforce_tcb_leaf`` attribute satisfies the requirement enforced by
  ``enforce_tcb`` for the marked function to be in the named TCB but does not
  continue to check the functions called from within the leaf function.

  - ``enforce_tcb_leaf(Name)`` indicates that this function is a part of the TCB named ``Name``
  }];
}
