//==--- 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):
//   sphinx-build -b html _build/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 MustTailDocs : Documentation {
  let Category = DocCatStmt;
  let Content = [{
If a ``return`` statement is marked ``musttail``, this indicates that the
compiler must generate a tail call for the program to be correct, even when
optimizations are disabled. This guarantees that the call will not cause
unbounded stack growth if it is part of a recursive cycle in the call graph.

If the callee is a virtual function that is implemented by a thunk, there is
no guarantee in general that the thunk tail-calls the implementation of the
virtual function, so such a call in a recursive cycle can still result in
unbounded stack growth.

``clang::musttail`` can only be applied to a ``return`` statement whose value
is the result of a function call (even functions returning void must use
``return``, although no value is returned). The target function must have the
same number of arguments as the caller. The types of the return value and all
arguments must be similar according to C++ rules (differing only in cv
qualifiers or array size), including the implicit "this" argument, if any.
Any variables in scope, including all arguments to the function and the
return value must be trivially destructible. The calling convention of the
caller and callee must match, and they must not be variadic functions or have
old style K&R C function declarations.
  }];
}

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 BTFDeclTagDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``__attribute__((btf_decl_tag("ARGUMENT")))`` attribute for
all targets. This attribute may be attached to a struct/union, struct/union
field, function, function parameter, variable or typedef declaration. If -g is
specified, the ``ARGUMENT`` info will be preserved in IR and be emitted to
dwarf. For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF
section too.
  }];
}

def BTFTypeTagDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
Clang supports the ``__attribute__((btf_type_tag("ARGUMENT")))`` attribute for
all targets. It only has effect when ``-g`` is specified on the command line and
is currently silently ignored when not applied to a pointer type (note: this
scenario may be diagnosed in the future).

The ``ARGUMENT`` string will be preserved in IR and emitted to DWARF for the
types used in variable declarations, function declarations, or typedef
declarations.

For BPF targets, the ``ARGUMENT`` string will also be emitted to .BTF ELF
section.
  }];
}

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 TargetClonesDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Clang supports the ``target_clones("OPTIONS")`` attribute. This attribute may be
attached to a function declaration and causes function multiversioning, where
multiple versions of the function will be emitted with different code
generation options.  Additionally, these versions will be resolved at runtime
based on the priority of their attribute options. All ``target_clone`` functions
are considered multiversioned functions.

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.

The options to ``target_clones`` can either be a target-specific architecture
(specified as ``arch=CPU``), or one of a list of subtarget features.

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.

The versions can either be listed as a comma-separated sequence of string
literals or as a single string literal containing a comma-separated list of
versions.  For compatibility with GCC, the two formats can be mixed.  For
example, the following will emit 4 versions of the function:

  .. code-block:: c++

    __attribute__((target_clones("arch=atom,avx2","arch=ivybridge","default")))
    void foo() {}

}];
}

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 NoProfileInstrumentFunctionDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use the ``no_profile_instrument_function`` attribute on a function declaration
to denote that the compiler should not instrument the function with
profile-related instrumentation, such as via the
``-fprofile-generate`` / ``-fprofile-instr-generate`` /
``-fcs-profile-generate`` / ``-fprofile-arcs`` flags.
}];
}

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 with the following accepted
values:
* all values accepted by ``-fno-sanitize=``;
* ``coverage``, to disable SanitizerCoverage instrumentation.

For example, ``__attribute__((no_sanitize("address", "thread")))`` specifies
that AddressSanitizer and ThreadSanitizer should not be applied to the function
or variable. Using ``__attribute__((no_sanitize("coverage")))`` specifies that
SanitizerCoverage should not be applied to the function.

See :ref:`Controlling Code Generation <controlling-code-generation>` for a
full list of supported sanitizer flags.
  }];
}

def DisableSanitizerInstrumentationDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use the ``disable_sanitizer_instrumentation`` attribute on a function,
Objective-C method, or global variable, to specify that no sanitizer
instrumentation should be applied.

This is not the same as ``__attribute__((no_sanitize(...)))``, which depending
on the tool may still insert instrumentation to prevent false positive reports.
  }];
}

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. GCC's loop unrolling hints
``#pragma GCC unroll`` and ``#pragma GCC nounroll`` are also supported and have
identical semantics to ``#pragma unroll`` and ``#pragma nounroll``.

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 RestrictDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "malloc";
  let Content = [{
The ``malloc`` attribute indicates that the function acts like a system memory
allocation function, returning a pointer to allocated storage disjoint from the
storage for any other object accessible to the caller.
  }];
}

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``
or ``swiftasynccall`` 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 SwiftAsyncCallDocs : Documentation {
  let Category = DocCatVariable;
  let Content = [{
The ``swiftasynccall`` attribute indicates that a function is
compatible with the low-level conventions of Swift async functions,
provided it declares the right formal arguments.

In most respects, this is similar to the ``swiftcall`` attribute, except for
the following:

- A parameter may be marked ``swift_async_context``, ``swift_context``
  or ``swift_indirect_result`` (with the same restrictions on parameter
  ordering as ``swiftcall``) but the parameter attribute
  ``swift_error_result`` is not permitted.

- A ``swiftasynccall`` function must have return type ``void``.

- Within a ``swiftasynccall`` function, a call to a ``swiftasynccall``
  function that is the immediate operand of a ``return`` statement is
  guaranteed to be performed as a tail call. This syntax is allowed even
  in C as an extension (a call to a void-returning function cannot be a
  return operand in standard C). If something in the calling function would
  semantically be performed after a guaranteed tail call, such as the
  non-trivial destruction of a local variable or temporary,
  then the program is ill-formed.
  }];
}

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

If the function is not ``swiftasynccall``, this attribute only generates
extended frame information.

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``
or ``swiftasynccall`` 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 BuiltinAliasDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "clang::builtin_alias, clang_builtin_alias";
  let Content = [{
This attribute is used in the implementation of the C intrinsics.
It allows the C intrinsic functions to be declared using the names defined
in target builtins, and still be recognized as clang builtins equivalent to the
underlying name. For example, ``riscv_vector.h`` declares the function ``vadd``
with ``__attribute__((clang_builtin_alias(__builtin_rvv_vadd_vv_i8m1)))``.
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/RISC-V
C intrinsic functions; it is intended for use only inside ``arm_*.h`` and
``riscv_*.h`` and is not a general mechanism for declaring arbitrary aliases
for clang builtin functions.
  }];
}

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.

In order to avoid duplicating the attribute definitions for similar
purpose for other architecture, there is a general form for the
attribute `clang_builtin_alias`.
  }];
}

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 UsingIfExistsDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
The ``using_if_exists`` attribute applies to a using-declaration. It allows
programmers to import a declaration that potentially does not exist, instead
deferring any errors to the point of use. For instance:

.. code-block:: c++

  namespace empty_namespace {};
  __attribute__((using_if_exists))
  using empty_namespace::does_not_exist; // no error!

  does_not_exist x; // error: use of unresolved 'using_if_exists'

The C++ spelling of the attribte (`[[clang::using_if_exists]]`) is also
supported as a clang extension, since ISO C++ doesn't support attributes in this
position. If the entity referred to by the using-declaration is found by name
lookup, the attribute has no effect. This attribute is useful for libraries
(primarily, libc++) that wish to redeclare a set of declarations in another
namespace, when the availability of those declarations is difficult or
impossible to detect at compile time with the preprocessor.
  }];
}

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. The attribute requires a string literal argument which used to
identify the handle with later uses of ``use_handle`` or
``release_handle``.

.. code-block:: c++

  // Output arguments from Zircon.
  zx_status_t zx_socket_create(uint32_t options,
                               zx_handle_t __attribute__((acquire_handle("zircon"))) * out0,
                               zx_handle_t* out1 [[clang::acquire_handle("zircon")]]);


  // Returned handle.
  [[clang::acquire_handle("tag")]] int open(const char *path, int oflag, ... );
  int open(const char *path, int oflag, ... ) __attribute__((acquire_handle("tag")));
  }];
}

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(tag)`` it is assumed to not to change
the state of the handle. It is also assumed to require an open handle to work with.
The attribute requires a string literal argument to identify the handle being used.

.. code-block:: c++

  zx_status_t zx_port_wait(zx_handle_t handle [[clang::use_handle("zircon")]],
                           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(tag)`` it is assumed to
close the handle. It is also assumed to require an open handle to work with. The
attribute requires a string literal argument to identify the handle being released.

.. code-block:: c++

  zx_status_t zx_handle_close(zx_handle_t handle [[clang::release_handle("tag")]]);
  }];
}

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``
  }];
}

def ErrorAttrDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "error, warning";
  let Content = [{
The ``error`` and ``warning`` function attributes can be used to specify a
custom diagnostic to be emitted when a call to such a function is not
eliminated via optimizations. This can be used to create compile time
assertions that depend on optimizations, while providing diagnostics
pointing to precise locations of the call site in the source.

.. code-block:: c++

  __attribute__((warning("oh no"))) void dontcall();
  void foo() {
    if (someCompileTimeAssertionThatsTrue)
      dontcall(); // Warning

    dontcall(); // Warning

    if (someCompileTimeAssertionThatsFalse)
      dontcall(); // No Warning
    sizeof(dontcall()); // No Warning
  }
  }];
}
