Thanks for documenting this! -- Sean Silva
On Tue, Jan 7, 2014 at 1:12 PM, Aaron Ballman <[email protected]>wrote: > Author: aaronballman > Date: Tue Jan 7 14:12:20 2014 > New Revision: 198705 > > URL: http://llvm.org/viewvc/llvm-project?rev=198705&view=rev > Log: > Updating the documentation about how to add attributes based on the rather > extensive refactorings that have happened over the past several months. > > Modified: > cfe/trunk/docs/InternalsManual.rst > > Modified: cfe/trunk/docs/InternalsManual.rst > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.rst?rev=198705&r1=198704&r2=198705&view=diff > > ============================================================================== > --- cfe/trunk/docs/InternalsManual.rst (original) > +++ cfe/trunk/docs/InternalsManual.rst Tue Jan 7 14:12:20 2014 > @@ -1588,47 +1588,146 @@ How to change Clang > How to add an attribute > ----------------------- > > -To add an attribute, you'll have to add it to the list of attributes, add > it to > -the parsing phase, and look for it in the AST scan. > -`r124217 <http://llvm.org/viewvc/llvm-project?view=rev&revision=124217>`_ > -has a good example of adding a warning attribute. > +Attribute Basics > +^^^^^^^^^^^^^^^^ > > -(Beware that this hasn't been reviewed/fixed by the people who designed > the > -attributes system yet.) > +Attributes in clang come in two forms: parsed form, and semantic form. > Both > +forms are represented via a tablegen definition of the attribute, > specified in > +Attr.td. > > > ``include/clang/Basic/Attr.td`` > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > -First, add your attribute to the `include/clang/Basic/Attr.td file > -< > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup > >`_. > +First, add your attribute to the `include/clang/Basic/Attr.td > +< > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup > >`_ > +file. > > Each attribute gets a ``def`` inheriting from ``Attr`` or one of its > subclasses. ``InheritableAttr`` means that the attribute also applies to > -subsequent declarations of the same name. > +subsequent declarations of the same name. ``InheritableParamAttr`` is > similar > +to ``InheritableAttr``, except that the attribute is written on a > parameter > +instead of a declaration, type or statement. Attributes inheriting from > +``TypeAttr`` are pure type attributes which generally are not given a > +representation in the AST. Attributes inheriting from > ``TargetSpecificAttr`` > +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. If you want to allow > the > -``[[]]`` C++11 syntax, you have to define a list of ``Namespaces``, which > will > -let users write ``[[namespace::spelling]]``. Using the empty string for a > -namespace will allow users to write just the spelling with no "``::``". > -Attributes which g++-4.8 accepts should also have a > -``CXX11<"gnu", "spelling">`` spelling. > +``[[here]]``. All such strings will be synonymous. Possible > ``Spellings`` > +are: ``GNU`` (for use with GNU-style __attribute__ spellings), > ``Declspec`` > +(for use with Microsoft Visual Studio-style __declspec spellings), > ``CXX11` > +(for use with C++11-style [[foo]] and [[foo::bar]] spellings), and > ``Keyword`` > +(for use with attributes that are implemented as keywords, like C++11's > +``override`` or ``final``). If you want to allow the ``[[]]`` C++11 > syntax, you > +have to define a list of ``Namespaces``, which will let users write > +``[[namespace::spelling]]``. Using the empty string for a namespace will > allow > +users to write just the spelling with no "``::``". Attributes which > g++-4.8 > +or later accepts should also have a ``CXX11<"gnu", "spelling">`` spelling. > > ``Subjects`` restricts what kinds of AST node to which this attribute can > -appertain (roughly, attach). > +appertain (roughly, attach). The subjects are specified via a > ``SubjectList``, > +which specify the list of subjects. Additionally, subject-related > diagnostics > +can be specified to be warnings or errors, with the default being a > warning. > +The diagnostics displayed to the user are automatically determined based > on > +the subjects in the list, but a custom diagnostic parameter can also be > +specified in the ``SubjectList``. The diagnostics generated for subject > list > +violations are either ``diag::warn_attribute_wrong_decl_type`` or > +``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is > +found in `include/clang/Sema/AttributeList.h > +< > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup > >`_ > +If you add new Decl nodes to the ``SubjectList``, you may need to update > 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 > >`_. > + > +Diagnostic checking for attribute subject lists is automated except when > +``HasCustomParsing`` is set to ``1``. > + > +By default, all subjects in the SubjectList must either be a Decl node > defined > +in ``DeclNodes.td``, or a statement node defined in ``StmtNodes.td``. > However, > +more complex subjects can be created by creating a ``SubsetSubject`` > object. > +Each such object has a base subject which it appertains to (which must be > a > +Decl or Stmt node, and not a SubsetSubject node), and some custom code > which 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. > > ``Args`` names the arguments the attribute takes, in order. If ``Args`` > is > ``[StringArgument<"Arg1">, IntArgument<"Arg2">]`` then > -``__attribute__((myattribute("Hello", 3)))`` will be a valid use. > +``__attribute__((myattribute("Hello", 3)))`` will be a valid use. > Attribute > +arguments specify both the parsed form and the semantic form of the > attribute. > +The previous example shows an attribute which requires two attributes > while > +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 > +``HasCustomParsing`` is set to ``1``, or when the attribute uses an > optional or > +variadic argument. Diagnostic checking for argument semantics is not > automated. > + > +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``. > + > +Custom accessors can be generated for an attribute based on the spelling > list > +for that attribute. For instance, if an attribute has two different > spellings: > +'Foo' and 'Bar', accessors can be created: > +``[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 > +``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. > + > +Attributes which do not require custom semantic handling should set the > +``SemaHandler`` field to ``0``. Note that anything inheriting from > +``IgnoredAttr`` automatically do not get a semantic handler. All other > +attributes are assumed to use a semantic handler by default. Attributes > +without a semantic handler are not given a parsed attribute Kind > enumeration. > + > +The ``LangOpts`` field can be used to specify a list of language options > +required by the attribute. For instance, all of the CUDA-specific > attributes > +specify ``[CUDA]`` for the ``LangOpts`` field, and when the CUDA language > +option is not enabled, an "attribute ignored" warning diagnostic is > emitted. > +Since language options are not table generated nodes, new language > options must > +be created manually and should specify the spelling used by > ``LangOptions`` class. > + > +Target-specific attribute sometimes share a spelling with other > attributes in > +different targets. For instance, the ARM and MSP430 targets both have an > +attribute spelled ``GNU<"interrupt">``, but with different parsing and > semantic > +requirements. To support this feature, an attribute inheriting from > +``TargetSpecificAttribute`` make 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 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. > + > +If additional functionality is desired for the semantic form of the > attribute, > +the ``AdditionalMembers`` field specifies code to be copied verbatim into > the > +semantic attribute class object. > > Boilerplate > ^^^^^^^^^^^ > > -Write a new ``HandleYourAttr()`` function in `lib/Sema/SemaDeclAttr.cpp > -< > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup > >`_, > -and add a case to the switch in ``ProcessNonInheritableDeclAttr()`` or > -``ProcessInheritableDeclAttr()`` forwarding to it. > +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 > >`_, > +and generally starts in the ``ProcessDeclAttribute`` function. If your > +attribute is a "simple" attribute -- meaning that it requires no custom > +semantic processing aside from what is automatically provided for you, > you can > +add a call to ``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the > switch > +statement. Otherwise, write a new ``handleYourAttr()`` function, and add > that > +to the switch statement. > > If your attribute causes extra warnings to fire, define a ``DiagGroup`` in > `include/clang/Basic/DiagnosticGroups.td > @@ -1638,6 +1737,10 @@ only defining one diagnostic, you can sk > ``InGroup<DiagGroup<"your-attribute">>`` directly in > `DiagnosticSemaKinds.td > < > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup > >`_ > > +All semantic diagnostics generated for your attribute, including > automatically- > +generated ones (such as subjects and argument counts), should have a > +corresponding test case. > + > The meat of your attribute > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
