Made considerable updates to the documentation explaining how to add a new attribute to clang. Cleans up some of the existing wording, as well as adding new information and better explanations.

llvm-svn: 237268
This commit is contained in:
Aaron Ballman 2015-05-13 18:06:48 +00:00
parent f428fcfaa0
commit d43f0c5e82
1 changed files with 255 additions and 143 deletions

View File

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