Brief :
Attributes are a form of additional data that are passed along with program constructs like functions or variables to compiler which allows for some special operations. For example, noreturn is an attribute that tells compiler that the function never returns. The keyword __attribute__ allows to specify attributes. Complete list of attributes supported by Clang can be found here.
In spite of providing a huge number of attributes, compilers often supports to add custom attributes. Here i am only going through the implementation details. You can find the documentation part here.Note : I assume that you have build Clang from sources, if you haven't follow this guide.
Implementation :
1. Fist step is add attribute definition to include/clang/Basic/Attr.td
def MyAttribute : InheritableAttr {
let Spellings = [GNU<"myAttribute">];
let Subjects = SubjectList<[Function]>;
let Documentation = [MyAttributeDocs];
}
InheritableAttr - specifies that the attribute can be inherited by later re-declarations of the Decl class.
Spellings - Specifies the ways in which the attribute can be spelled.
Subjects - Program constructs that the attribute is associated with.
Documentation - Each attribute must specify its behavior in the document.
2. Documentation should be added in include/clang/Basic/AttrDocs.td
def MyAttributeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Here goes ``myAttribute`` documentation.
}];
}
Category - Specifies which subject category it belongs to. [DocCatFunction, DocCatVariable,DocCatType, DocCatStmt]
Once we add an attribute definition, we can check whether attribute is added or not by the clang-tblgen too. If AttributeReference.rst contains your attribute, we are good to go.
$ 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
3. All semantic processing of declaration attributes happens in lib/Sema/SemaDeclAttr.cpp. Add a switch case to ProcessDeclAttribute().
case ParsedAttr::AT_MyAttribute:
handleSimpleAttribute<MyAttributeAttr>(S, D, AL);
break;
4. Final step is to use the attribute we just added to clang. we need to implement the custom logic that is required.
The clang::Decl object's hasAttr<T>() can be used to check the presence or absence of an attribute. To obtain a pointer to the semantic representation of the attribute, getAttr<T> may be used.
Since the attribute we added is an Function attribute we should add the logic in CGCall::ConstructAttributeList()
if (TargetDecl && TargetDecl->hasAttr<MyAttributeAttr>()) {
// Add your custom logic.
}
Hope this helps :)
Cheers,
Harry
Comments
Post a Comment