LLVM每日談之十四 如何給Clang添加一個屬性

這次次內容主要出自文檔: 「Clang」 CFE Internals Manual

地址: 「Clang」 CFE Internals Manual

在這個文檔中,以簡明的的一個例子說明了如何按照這個方式在Clang中添加一個屬性。講的很清楚,我在這裡不再累述,只是將例子中的部分代碼和文檔結合起來,一起展現給大家。

How to add an attribute?

To add an attribute, you』ll have to add it to the list of attributes, add it tothe parsing phase, and look for it in the AST scan.r124217 has a good example of adding a warning attribute.

(Beware that this hasn』t been reviewed/fixed by the people who designed theattributes system yet.)

include/clang/Basic/Attr.td

First, add your attribute to the include/clang/Basic/Attr.td file.

Each attribute gets a def inheriting fromAttr or one of itssubclasses.InheritableAttr means that the attribute also applies tosubsequent declarations of the same name.

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 ofNamespaces, which willlet users write[[namespace::spelling]]. Using the empty string for anamespace will allow users to write just the spelling with no 「::」.Attributes which g++-4.8 accepts should also have a CXX11<"gnu","spelling"> spelling.

Subjects restricts what kinds of AST node to which this attribute canappertain (roughly, attach).

Args names the arguments the attribute takes, in order. IfArgs is [StringArgument<"Arg1">, IntArgument<"Arg2">] then__attribute__((myattribute("Hello",3))) will be a valid use.

--- cfe/trunk/include/clang/Basic/Attr.tdt2011/01/25 19:39:31t124216n+++ cfe/trunk/include/clang/Basic/Attr.tdt2011/01/25 20:08:12t124217n@@ -232,6 +232,11 @@n let Spellings = [];n }n n+def ForbidTemporaries : Attr {n+ let Spellings = ["forbid_temporaries"];n+ let Subjects = [CXXRecord];n+}n+n def Format : InheritableAttr {n let Spellings = ["format"];n let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,n

Boilerplate

Write a new HandleYourAttr() function inlib/Sema/SemaDeclAttr.cpp,and add a case to the switch in ProcessNonInheritableDeclAttr() orProcessInheritableDeclAttr() forwarding to it.

If your attribute causes extra warnings to fire, define a DiagGroup in include/clang/Basic/DiagnosticGroups.td named after the attribute』s Spelling with 「_」s replaced by 「-「s. If you』reonly defining one diagnostic, you can skipDiagnosticGroups.td and useInGroup<DiagGroup<"your-attribute">> directly inDiagnosticSemaKinds.td

--- cfe/trunk/lib/Sema/SemaDeclAttr.cppt2011/01/25 19:39:31t124216n+++ cfe/trunk/lib/Sema/SemaDeclAttr.cppt2011/01/25 20:08:12t124217n@@ -885,6 +885,24 @@n d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));n }n n+static void HandleForbidTemporariesAttr(Decl *d, const AttributeList &Attr,n+ Sema &S) {n+ assert(Attr.isInvalid() == false);n+n+ if (Attr.getNumArgs() != 0) {n+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;n+ return;n+ }n+n+ if (!isa<TypeDecl>(d)) {n+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)n+ << Attr.getName() << 9 /*class*/;n+ return;n+ }n+n+ d->addAttr(::new (S.Context) ForbidTemporariesAttr(Attr.getLoc(), S.Context));n+}n+n static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {n if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {n S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)n@@ -2674,6 +2692,8 @@n case AttributeList::AT_ext_vector_type:n HandleExtVectorTypeAttr(scope, D, Attr, S);n break;n+ case AttributeList::AT_forbid_temporaries:n+ HandleForbidTemporariesAttr(D, Attr, S); break;n case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;n case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;n case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break;n

The meat of your attribute

Find an appropriate place in Clang to do whatever your attribute needs to do.Check for the attribute』s presence usingDecl::getAttr<YourAttr>().

Update the Clang Language Extensions document to describe your new attribute.

2013年6月4日

推薦閱讀:

在編譯C語言代碼時,Clang跟gcc編譯器哪一個編譯出來的程序運行更快?特別是在浮點運算方面。
誰說不能與龍一起跳舞:Clang / LLVM (2)
Clang parser是完全手寫的嗎?

TAG:LLVM | Clang | ChrisLattner |