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

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

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

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

.. |br| raw:: html

  <br/>

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

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

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

def 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 = DocCatFunction;
  let Content = [{
If a statement is marked ``nomerge`` and contains call experessions, 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.
  }];
}

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, or for a variable that is not a parameter or a non-static
data member.
  }];
}

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.

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
substatement of an ``if`` or ``else`` 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;
  }


At the moment the attribute only has effect when used in an ``if`` or ``else``
statement.

.. 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.

  }];
}

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_acceess_index()``.
  }];
}

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

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

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

The semantics are as follows:

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

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

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

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

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

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

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

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

These attributes have no effect for position-independent code.

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

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

These attributes have no effect for position-independent code.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  .. code-block:: c++

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def NoSanitizeDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
Use the ``no_sanitize`` attribute on a function or a global variable
declaration to specify that a particular instrumentation or set of
instrumentations should not be applied. The attribute takes a list of
string literals, which have the same meaning as values accepted by the
``-fno-sanitize=`` flag. For example,
``__attribute__((no_sanitize("address", "thread")))`` specifies that
AddressSanitizer and ThreadSanitizer should not be applied to the
function or variable.

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

def NoSanitizeAddressDocs : Documentation {
  let Category = DocCatFunction;
  // This function has multiple distinct spellings, and so it requires a custom
  // heading to be specified. The most common spelling is sufficient.
  let Heading = "no_sanitize_address, no_address_safety_analysis";
  let Content = [{
.. _langext-address_sanitizer:

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

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

Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
specify that checks for data races on plain (non-atomic) memory accesses should
not be inserted by ThreadSanitizer. The function is still instrumented by the
tool to avoid false positives and provide meaningful stack traces.
  }];
}

def NoSanitizeMemoryDocs : Documentation {
  let Category = DocCatFunction;
  let Heading = "no_sanitize_memory";
  let Content = [{
.. _langext-memory_sanitizer:

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

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

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

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

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

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

.. code-block:: c++

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

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

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

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

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

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

For example:

.. code-block:: c++

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

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

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

For example:

.. code-block:: c++

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

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

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

Clang supports annotating type tags of two forms.

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

    .. code-block:: c++

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

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

    .. code-block:: c++

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


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

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

    .. code-block:: c++

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

      #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)

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

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

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

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

    .. code-block:: c++

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

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

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

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

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

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

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

Clang implements two kinds of checks with this attribute.

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

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

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

   .. code-block:: c

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

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

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

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

   Another example:

   .. code-block:: c

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

       vprintf(s, ap); // warning
     }

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

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

   .. code-block:: c

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

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

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

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

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

For example, consider the following C code:

.. code-block:: c

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

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

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

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

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

.. code-block:: c

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

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

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

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

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

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

  }];
}

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

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

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

This attribute provides an experimental implementation of the facility
described in the C++ committee paper `P0936R0 <http://wg21.link/p0936r0>`_,
and is subject to change as the design of the corresponding functionality
changes.
  }];
}

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

  .. code-block:: c++

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

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

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

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

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

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

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

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

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

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

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

.. code-block:: c++

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

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

.. code-block:: c++

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

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

.. code-block:: c++

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

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

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

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

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

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

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

.. code-block:: c++

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

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

.. code-block:: c++

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

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

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

.. code-block:: c++

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

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

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

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

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

  .. code-block:: c++

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

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

  .. code-block:: c++

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

  }];
}

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

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

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

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

.. code-block:: c

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

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

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

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

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

  .. code-block:: c

    __constant int c = ...;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

  .. code-block:: c

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

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

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

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

  .. code-block:: objective-c

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

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

  .. code-block:: c

    int fetch(int * _Nonnull ptr);

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

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

  .. code-block:: c

    int fetch_or_zero(int * _Nullable ptr);

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

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

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

  .. code-block:: c

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

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

  .. code-block:: c

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

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

  .. code-block:: c

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

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

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

  .. code-block:: c

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

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

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

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

The ``ns_error_domain`` attribute indicates a global ``NSString`` 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 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:: c

    @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 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

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.

  }];
}

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. It has no effect on indirect calls. Virtual functions, 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);
    }

Marking virtual functions as ``not_tail_called`` is an error:

  .. code-block:: c++

    class Base {
    public:
      // not_tail_called on a virtual function is an error.
      [[clang::not_tail_called]] virtual int foo1();

      virtual int foo2();

      // Non-virtual functions can be marked ``not_tail_called``.
      [[clang::not_tail_called]] int foo3();
    };

    class Derived1 : public Base {
    public:
      int foo1() override;

      // not_tail_called on a virtual function is an error.
      [[clang::not_tail_called]] int foo2() override;
    };
  }];
}

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

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

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

  .. code-block:: c++

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

    template class basic_string<char>;

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

  .. code-block:: c++

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

    template class basic_string<char>;

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

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

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

For example:

  .. code-block:: c

    int callee(int);

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

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

  .. code-block:: c++

    int callee(int);

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

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

  }];
}

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

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

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

For example:

  .. code-block:: c

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

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

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

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

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

  .. code-block:: c

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

  }];
}

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

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

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

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

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

  - First, remove any empty direct results.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def 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 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.
}];
}

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 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 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 LifetimeOwnerDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
.. Note:: This attribute is experimental and its effect on analysis is subject to change in
  a future version of clang.

The attribute ``[[gsl::Owner(T)]]`` applies to structs and classes that own an
object of type ``T``:

.. code::

  class [[gsl::Owner(int)]] IntOwner {
  private:
    int value;
  public:
    int *getInt() { return &value; }
  };

The argument ``T`` is optional and is ignored.
This attribute may be used by analysis tools and has no effect on code
generation. A ``void`` argument means that the class can own any type.

See Pointer_ for an example.
}];
}

def LifetimePointerDocs : Documentation {
  let Category = DocCatDecl;
  let Content = [{
.. Note:: This attribute is experimental and its effect on analysis is subject to change in
  a future version of clang.

The attribute ``[[gsl::Pointer(T)]]`` applies to structs and classes that behave
like pointers to an object of type ``T``:

.. code::

  class [[gsl::Pointer(int)]] IntPointer {
  private:
    int *valuePointer;
  public:
    int *getInt() { return &valuePointer; }
  };

The argument ``T`` is optional and is ignored.
This attribute may be used by analysis tools and has no effect on code
generation. A ``void`` argument means that the pointer can point to any type.

Example:
When constructing an instance of a class annotated like this (a Pointer) from
an instance of a class annotated with ``[[gsl::Owner]]`` (an Owner),
then the analysis will consider the Pointer to point inside the Owner.
When the Owner's lifetime ends, it will consider the Pointer to be dangling.

.. code-block:: c++

  int f() {
    IntPointer P;
    if (true) {
      IntOwner O(7);
      P = IntPointer(O); // P "points into" O
    } // P is dangling
    return P.get(); // error: Using a dangling Pointer.
  }

}];
}

def ArmBuiltinAliasDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
This attribute is used in the implementation of the ACLE intrinsics.
It allows the intrinsic functions to
be declared using the names defined in ACLE, and still be recognized
as clang builtins equivalent to the underlying name. For example,
``arm_mve.h`` declares the function ``vaddq_u32`` with
``__attribute__((__clang_arm_mve_alias(__builtin_arm_mve_vaddq_u32)))``,
and similarly, one of the type-overloaded declarations of ``vaddq``
will have the same attribute. This ensures that both functions are
recognized as that clang builtin, and in the latter case, the choice
of which builtin to identify the function as can be deferred until
after overload resolution.

This attribute can only be used to set up the aliases for certain Arm
intrinsic functions; it is intended for use only inside ``arm_*.h``
and is not a general mechanism for declaring arbitrary aliases for
clang builtin functions.
  }];
}

def NoBuiltinDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
.. Note:: This attribute is not yet fully implemented, it is validated but has
          no effect on the generated code.

The ``__attribute__((no_builtin))`` is similar to the ``-fno-builtin`` flag
except it is specific to the body of a function. The attribute may also be
applied to a virtual function but has no effect on the behavior of overriding
functions in a derived class.

It accepts one or more strings corresponding to the specific names of the
builtins to disable (e.g. "memcpy", "memset").
If the attribute is used without parameters it will disable all buitins at
once.

.. code-block:: c++

  // The compiler is not allowed to add any builtin to foo's body.
  void foo(char* data, size_t count) __attribute__((no_builtin)) {
    // The compiler is not allowed to convert the loop into
    // `__builtin_memset(data, 0xFE, count);`.
    for (size_t i = 0; i < count; ++i)
      data[i] = 0xFE;
  }

  // The compiler is not allowed to add the `memcpy` builtin to bar's body.
  void bar(char* data, size_t count) __attribute__((no_builtin("memcpy"))) {
    // The compiler is allowed to convert the loop into
    // `__builtin_memset(data, 0xFE, count);` but cannot generate any
    // `__builtin_memcpy`
    for (size_t i = 0; i < count; ++i)
      data[i] = 0xFE;
  }
  }];
}

def HandleDocs : DocumentationCategory<"Handle Attributes"> {
  let Content = [{
Handles are a way to identify resources like files, sockets, and processes.
They are more opaque than pointers and widely used in system programming. They
have similar risks such as never releasing a resource associated with a handle,
attempting to use a handle that was already released, or trying to release a
handle twice. Using the annotations below it is possible to make the ownership
of the handles clear: whose responsibility is to release them. They can also
aid static analysis tools to find bugs.
  }];
}

def AcquireHandleDocs : Documentation {
  let Category = HandleDocs;
  let Content = [{
If this annotation is on a function or a function type it is assumed to return
a new handle. In case this annotation is on an output parameter,
the function is assumed to fill the corresponding argument with a new
handle.

.. code-block:: c++

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


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

def UseHandleDocs : Documentation {
  let Category = HandleDocs;
  let Content = [{
A function taking a handle by value might close the handle. If a function
parameter is annotated with ``use_handle`` it is assumed to not to change
the state of the handle. It is also assumed to require an open handle to work with.

.. code-block:: c++

  zx_status_t zx_port_wait(zx_handle_t handle [[clang::use_handle]],
                           zx_time_t deadline,
                           zx_port_packet_t* packet);
  }];
}

def ReleaseHandleDocs : Documentation {
  let Category = HandleDocs;
  let Content = [{
If a function parameter is annotated with ``release_handle`` it is assumed to
close the handle. It is also assumed to require an open handle to work with.

.. code-block:: c++

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

def ArmSveVectorBitsDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
The ``arm_sve_vector_bits(N)`` attribute is defined by the Arm C Language
Extensions (ACLE) for SVE. It is used to define fixed-length (VLST) variants of
sizeless types (VLAT).

For example:

.. code-block:: c

  #include <arm_sve.h>

  #if __ARM_FEATURE_SVE_BITS==512
  typedef svint32_t fixed_svint32_t __attribute__((arm_sve_vector_bits(512)));
  #endif

Creates a type ``fixed_svint32_t`` that is a fixed-length variant of
``svint32_t`` that contains exactly 512-bits. Unlike ``svint32_t``, this type
can be used in globals, structs, unions, and arrays, all of which are
unsupported for sizeless types.

The attribute can be attached to a single SVE vector (such as ``svint32_t``) or
to the SVE predicate type ``svbool_t``, this excludes tuple types such as
``svint32x4_t``. The behavior of the attribute is undefined unless
``N==__ARM_FEATURE_SVE_BITS``, the implementation defined feature macro that is
enabled under the ``-msve-vector-bits`` flag.

For more information See `Arm C Language Extensions for SVE
<https://developer.arm.com/documentation/100987/latest>`_ for more information.
}];
}

def ArmMveStrictPolymorphismDocs : Documentation {
    let Category = DocCatType;
    let Content = [{
This attribute is used in the implementation of the ACLE intrinsics for the Arm
MVE instruction set. It is used to define the vector types used by the MVE
intrinsics.

Its effect is to modify the behavior of a vector type with respect to function
overloading. If a candidate function for overload resolution has a parameter
type with this attribute, then the selection of that candidate function will be
disallowed if the actual argument can only be converted via a lax vector
conversion. The aim is to prevent spurious ambiguity in ARM MVE polymorphic
intrinsics.

.. code-block:: c++

  void overloaded(uint16x8_t vector, uint16_t scalar);
  void overloaded(int32x4_t vector, int32_t scalar);
  uint16x8_t myVector;
  uint16_t myScalar;

  // myScalar is promoted to int32_t as a side effect of the addition,
  // so if lax vector conversions are considered for myVector, then
  // the two overloads are equally good (one argument conversion
  // each). But if the vector has the __clang_arm_mve_strict_polymorphism
  // attribute, only the uint16x8_t,uint16_t overload will match.
  overloaded(myVector, myScalar + 1);

However, this attribute does not prohibit lax vector conversions in contexts
other than overloading.

.. code-block:: c++

  uint16x8_t function();

  // This is still permitted with lax vector conversion enabled, even
  // if the vector types have __clang_arm_mve_strict_polymorphism
  int32x4_t result = function();

    }];
}

def ArmCmseNSCallDocs : Documentation {
  let Category = DocCatType;
  let Content = [{
This attribute declares a non-secure function type.  When compiling for secure
state, a call to such a function would switch from secure to non-secure state.
All non-secure function calls must happen only through a function pointer, and
a non-secure function type should only be used as a base type of a pointer.
See `ARMv8-M Security Extensions: Requirements on Development
Tools - Engineering Specification Documentation
<https://developer.arm.com/docs/ecm0359818/latest/>`_ for more information.
  }];
}

def ArmCmseNSEntryDocs : Documentation {
  let Category = DocCatFunction;
  let Content = [{
This attribute declares a function that can be called from non-secure state, or
from secure state. Entering from and returning to non-secure state would switch
to and from secure state, respectively, and prevent flow of information
to non-secure state, except via return values. See `ARMv8-M Security Extensions:
Requirements on Development Tools - Engineering Specification Documentation
<https://developer.arm.com/docs/ecm0359818/latest/>`_ for more information.
  }];
}
