This answer表示clang post revision 165082应保留AST中所有已解析的属性。
我首先认为这意味着将保留所有属性,但似乎并非如此:
$ clang++ -v
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
$ cat att.cpp
void f [[noreturn, foo]] () {}
$ clang++ att.cpp -Xclang -ast-dump -fsyntax-only -std=c++11
att.cpp:1:20: warning: unknown attribute 'foo' ignored [-Wattributes]
void f [[noreturn, foo]] () {}
^
att.cpp:1:30: warning: function declared 'noreturn' should not return [-Winvalid-noreturn]
void f [[noreturn, foo]] () {}
^
TranslationUnitDecl 0x102021cd0 <<invalid sloc>>
|-TypedefDecl 0x102022210 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x102022270 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x102022630 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
`-FunctionDecl 0x1020226d0 <att.cpp:1:1, col:30> f 'void (void)'
|-CompoundStmt 0x1020227b0 <col:29, col:30>
`-CXX11NoReturnAttr 0x102022770 <col:10>
2 warnings generated.
在上面,请注意属性'foo'确实被忽略了,并且不存在于AST中,而不是属性'noreturn'。
属性'foo'会在某个时刻保留在AST中,或者所有属性都必须是实际编译器的一部分(在Attr.td等中定义,如Clang Internals Manual中所述)是保留在AST?
答案 0 :(得分:2)
如果Clang已经知道属性,那么这些属性只保留在AST中,而Clang是大多数GCC属性和clang定义的属性。但是,您可以使用this link中的提示添加自己的属性。这使您可以定义任何新属性,然后以下列方式在ast中处理它: 例如,您从上面的链接中获取了代码行
__attribute__((annotate("async")) uint c;
然后在RecursiveASTVisitor实例化中,您可以执行以下操作:
bool MyRecursiveASTVisitor::VisitVarDecl(VarDecl* v)
{
v->dump();
if(v->hasAttrs()){
clang::AttrVec vec = v->getAttrs();
printf("%s\n",vec[0]->getSpelling());
printf("%s\n", Lexer::getSourceText(
CharSourceRange::getTokenRange(
vec[0]->getRange()),
compiler.getSourceManager(),
langOpts).str().c_str());
}
return true;
}
第一个printf只打印&#34; annotate&#34;因为这是原始属性,为了获得有意义的值,我们将词法分析器中的实际标记作为字符串。
由于我们没有创建新属性,我们只获得了追加属性类型,但我们可以进一步挖掘并区分新创建的属性。不像新创建的属性那样优雅(尽管可能需要更改clang代码本身),但仍然有效。