<div dir="ltr">Thanks for documenting this!<div><br></div><div>-- Sean Silva</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 7, 2014 at 1:12 PM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: aaronballman<br>
Date: Tue Jan  7 14:12:20 2014<br>
New Revision: 198705<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=198705&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=198705&view=rev</a><br>
Log:<br>
Updating the documentation about how to add attributes based on the rather extensive refactorings that have happened over the past several months.<br>
<br>
Modified:<br>
    cfe/trunk/docs/InternalsManual.rst<br>
<br>
Modified: cfe/trunk/docs/InternalsManual.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.rst?rev=198705&r1=198704&r2=198705&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.rst?rev=198705&r1=198704&r2=198705&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/docs/InternalsManual.rst (original)<br>
+++ cfe/trunk/docs/InternalsManual.rst Tue Jan  7 14:12:20 2014<br>
@@ -1588,47 +1588,146 @@ How to change Clang<br>
 How to add an attribute<br>
 -----------------------<br>
<br>
-To add an attribute, you'll have to add it to the list of attributes, add it to<br>
-the parsing phase, and look for it in the AST scan.<br>
-`r124217 <<a href="http://llvm.org/viewvc/llvm-project?view=rev&revision=124217" target="_blank">http://llvm.org/viewvc/llvm-project?view=rev&revision=124217</a>>`_<br>
-has a good example of adding a warning attribute.<br>
+Attribute Basics<br>
+^^^^^^^^^^^^^^^^<br>
<br>
-(Beware that this hasn't been reviewed/fixed by the people who designed the<br>
-attributes system yet.)<br>
+Attributes in clang come in two forms: parsed form, and semantic form. Both<br>
+forms are represented via a tablegen definition of the attribute, specified in<br>
+Attr.td.<br>
<br>
<br>
 ``include/clang/Basic/Attr.td``<br>
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
<br>
-First, add your attribute to the `include/clang/Basic/Attr.td file<br>
-<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup</a>>`_.<br>
+First, add your attribute to the `include/clang/Basic/Attr.td<br>
+<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup</a>>`_<br>
+file.<br>
<br>
 Each attribute gets a ``def`` inheriting from ``Attr`` or one of its<br>
 subclasses.  ``InheritableAttr`` means that the attribute also applies to<br>
-subsequent declarations of the same name.<br>
+subsequent declarations of the same name.  ``InheritableParamAttr`` is similar<br>
+to ``InheritableAttr``, except that the attribute is written on a parameter<br>
+instead of a declaration, type or statement.  Attributes inheriting from<br>
+``TypeAttr`` are pure type attributes which generally are not given a<br>
+representation in the AST.  Attributes inheriting from ``TargetSpecificAttr``<br>
+are attributes specific to one or more target architectures.  An attribute that<br>
+inherits from ``IgnoredAttr`` is parsed, but will generate an ignored attribute<br>
+diagnostic when used.  The attribute type may be useful when an attribute is<br>
+supported by another vendor, but not supported by clang.<br>
<br>
 ``Spellings`` lists the strings that can appear in ``__attribute__((here))`` or<br>
-``[[here]]``.  All such strings will be synonymous.  If you want to allow the<br>
-``[[]]`` C++11 syntax, you have to define a list of ``Namespaces``, which will<br>
-let users write ``[[namespace::spelling]]``.  Using the empty string for a<br>
-namespace will allow users to write just the spelling with no "``::``".<br>
-Attributes which g++-4.8 accepts should also have a<br>
-``CXX11<"gnu", "spelling">`` spelling.<br>
+``[[here]]``.  All such strings will be synonymous.  Possible ``Spellings``<br>
+are: ``GNU`` (for use with GNU-style __attribute__ spellings), ``Declspec``<br>
+(for use with Microsoft Visual Studio-style __declspec spellings), ``CXX11`<br>
+(for use with C++11-style [[foo]] and [[foo::bar]] spellings), and ``Keyword``<br>
+(for use with attributes that are implemented as keywords, like C++11's<br>
+``override`` or ``final``). If you want to allow the ``[[]]`` C++11 syntax, you<br>
+have to define a list of ``Namespaces``, which will let users write<br>
+``[[namespace::spelling]]``.  Using the empty string for a namespace will allow<br>
+users to write just the spelling with no "``::``".  Attributes which g++-4.8<br>
+or later accepts should also have a ``CXX11<"gnu", "spelling">`` spelling.<br>
<br>
 ``Subjects`` restricts what kinds of AST node to which this attribute can<br>
-appertain (roughly, attach).<br>
+appertain (roughly, attach).  The subjects are specified via a ``SubjectList``,<br>
+which specify the list of subjects. Additionally, subject-related diagnostics<br>
+can be specified to be warnings or errors, with the default being a warning.<br>
+The diagnostics displayed to the user are automatically determined based on<br>
+the subjects in the list, but a custom diagnostic parameter can also be<br>
+specified in the ``SubjectList``.  The diagnostics generated for subject list<br>
+violations are either ``diag::warn_attribute_wrong_decl_type`` or<br>
+``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is<br>
+found in `include/clang/Sema/AttributeList.h<br>
+<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup</a>>`_<br>

+If you add new Decl nodes to the ``SubjectList``, you may need to update the<br>
+logic used to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp<br>
+<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup</a>>`_.<br>

+<br>
+Diagnostic checking for attribute subject lists is automated except when<br>
+``HasCustomParsing`` is set to ``1``.<br>
+<br>
+By default, all subjects in the SubjectList must either be a Decl node defined<br>
+in ``DeclNodes.td``, or a statement node defined in ``StmtNodes.td``.  However,<br>
+more complex subjects can be created by creating a ``SubsetSubject`` object.<br>
+Each such object has a base subject which it appertains to (which must be a<br>
+Decl or Stmt node, and not a SubsetSubject node), and some custom code which is<br>
+called when determining whether an attribute appertains to the subject.  For<br>
+instance, a ``NonBitField`` SubsetSubject appertains to a ``FieldDecl``, and<br>
+tests whether the given FieldDecl is a bit field.  When a SubsetSubject is<br>
+specified in a SubjectList, a custom diagnostic parameter must also be provided.<br>
<br>
 ``Args`` names the arguments the attribute takes, in order.  If ``Args`` is<br>
 ``[StringArgument<"Arg1">, IntArgument<"Arg2">]`` then<br>
-``__attribute__((myattribute("Hello", 3)))`` will be a valid use.<br>
+``__attribute__((myattribute("Hello", 3)))`` will be a valid use.  Attribute<br>
+arguments specify both the parsed form and the semantic form of the attribute.<br>
+The previous example shows an attribute which requires two attributes while<br>
+parsing, and the Attr subclass' constructor for the attribute will require a<br>
+string and integer argument.<br>
+<br>
+Diagnostic checking for argument counts is automated except when<br>
+``HasCustomParsing`` is set to ``1``, or when the attribute uses an optional or<br>
+variadic argument.  Diagnostic checking for argument semantics is not automated.<br>
+<br>
+If the parsed form of the attribute is more complex, or differs from the<br>
+semantic form, the ``HasCustomParsing`` bit can be set to ``1`` for the class,<br>
+and the parsing code in `Parser::ParseGNUAttributeArgs<br>
+<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup</a>>`_<br>
+can be updated for the special case.  Note that this only applies to arguments<br>
+with a GNU spelling -- attributes with a __declspec spelling currently ignore<br>
+this flag and are handled by ``Parser::ParseMicrosoftDeclSpec``.<br>
+<br>
+Custom accessors can be generated for an attribute based on the spelling list<br>
+for that attribute.  For instance, if an attribute has two different spellings:<br>
+'Foo' and 'Bar', accessors can be created:<br>
+``[Accessor<"isFoo", [GNU<"Foo">]>, Accessor<"isBar", [GNU<"Bar">]>]``<br>
+These accessors will be generated on the semantic form of the attribute,<br>
+accepting no arguments and returning a Boolean.<br>
+<br>
+Attributes which do not require an AST node should set the ``ASTNode`` field to<br>
+``0`` to avoid polluting the AST.  Note that anything inheriting from<br>
+``TypeAttr`` or ``IgnoredAttr`` automatically do not generate an AST node.  All<br>
+other attributes generate an AST node by default.  The AST node is the semantic<br>
+representation of the attribute.<br>
+<br>
+Attributes which do not require custom semantic handling should set the<br>
+``SemaHandler`` field to ``0``.  Note that anything inheriting from<br>
+``IgnoredAttr`` automatically do not get a semantic handler.  All other<br>
+attributes are assumed to use a semantic handler by default.  Attributes<br>
+without a semantic handler are not given a parsed attribute Kind enumeration.<br>
+<br>
+The ``LangOpts`` field can be used to specify a list of language options<br>
+required by the attribute.  For instance, all of the CUDA-specific attributes<br>
+specify ``[CUDA]`` for the ``LangOpts`` field, and when the CUDA language<br>
+option is not enabled, an "attribute ignored" warning diagnostic is emitted.<br>
+Since language options are not table generated nodes, new language options must<br>
+be created manually and should specify the spelling used by ``LangOptions`` class.<br>
+<br>
+Target-specific attribute sometimes share a spelling with other attributes in<br>
+different targets.  For instance, the ARM and MSP430 targets both have an<br>
+attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic<br>
+requirements.  To support this feature, an attribute inheriting from<br>
+``TargetSpecificAttribute`` make specify a ``ParseKind`` field.  This field<br>
+should be the same value between all arguments sharing a spelling, and<br>
+corresponds to the parsed attribute's Kind enumeration.  This allows attributes<br>
+to share a parsed attribute kind, but have distinct semantic attribute classes.<br>
+For instance, ``AttributeList::AT_Interrupt`` is the shared parsed attribute<br>
+kind, but ARMInterruptAttr and MSP430InterruptAttr are the semantic attributes<br>
+generated.<br>
+<br>
+If additional functionality is desired for the semantic form of the attribute,<br>
+the ``AdditionalMembers`` field specifies code to be copied verbatim into the<br>
+semantic attribute class object.<br>
<br>
 Boilerplate<br>
 ^^^^^^^^^^^<br>
<br>
-Write a new ``HandleYourAttr()`` function in `lib/Sema/SemaDeclAttr.cpp<br>
-<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup</a>>`_,<br>
-and add a case to the switch in ``ProcessNonInheritableDeclAttr()`` or<br>
-``ProcessInheritableDeclAttr()`` forwarding to it.<br>
+All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp<br>
+<<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup</a>>`_,<br>
+and generally starts in the ``ProcessDeclAttribute`` function.  If your<br>
+attribute is a "simple" attribute -- meaning that it requires no custom<br>
+semantic processing aside from what is automatically  provided for you, you can<br>
+add a call to ``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the switch<br>
+statement. Otherwise, write a new ``handleYourAttr()`` function, and add that<br>
+to the switch statement.<br>
<br>
 If your attribute causes extra warnings to fire, define a ``DiagGroup`` in<br>
 `include/clang/Basic/DiagnosticGroups.td<br>
@@ -1638,6 +1737,10 @@ only defining one diagnostic, you can sk<br>
 ``InGroup<DiagGroup<"your-attribute">>`` directly in `DiagnosticSemaKinds.td<br>
 <<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup</a>>`_<br>

<br>
+All semantic diagnostics generated for your attribute, including automatically-<br>
+generated ones (such as subjects and argument counts), should have a<br>
+corresponding test case.<br>
+<br>
 The meat of your attribute<br>
 ^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>