我想在下面的例子中解析类成员函数的通用属性:
class Foo
{
public:
void foo [[interesting]] ();
void bar ();
};
使用 libclang C API,我想在源代码中区分foo
和bar
(并且知道foo
具有interesting
属性)。这可能吗?我很难找到解释 API 中使用的概念的示例或文档(我找到了一个参考资料,但是当没有解释这些概念时,这有点难以使用)。
我想在下面的例子中解析类成员函数的通用属性:
class Foo
{
public:
void foo [[interesting]] ();
void bar ();
};
使用 libclang C API,我想在源代码中区分foo
和bar
(并且知道foo
具有interesting
属性)。这可能吗?我很难找到解释 API 中使用的概念的示例或文档(我找到了一个参考资料,但是当没有解释这些概念时,这有点难以使用)。
虽然我无法在 AST 中找到通用属性(似乎它们在构建 AST 时或之前被删除,而不是在它之后),但我确实找到了一种解决方法。
有annotate
如下形式的 clang 属性:
__attribute__((annotate("something")))
使用宏,我可以获得合理的语法和在 AST 中可见的注释:
#define INTERESTING __attribute__((annotate("interesting")))
class Foo
{
public:
INTERESTING void foo();
void bar();
};
该属性将是方法节点的子节点,其 display_name 是注释字符串。一个可能的 AST 转储:
<CursorKind.TRANSLATION_UNIT>
"test.h"
{
__builtin_va_list <CursorKind.TYPEDEF_DECL>
"__builtin_va_list"
type_info <CursorKind.CLASS_DECL>
"type_info"
Foo <CursorKind.CLASS_DECL>
"Foo"
{
<CursorKind.CXX_ACCESS_SPEC_DECL>
""
foo <CursorKind.CXX_METHOD>
"foo()"
{
<CursorKind.ANNOTATE_ATTR>
"interesting"
}
bar <CursorKind.CXX_METHOD>
"bar()"
}
}
它也产生相同的输出void foo INTERESTING ();
。
类似以下first_attr
函数的内容将获取传递的游标的第一个属性的游标(如果存在),或者如果不存在则获取空游标(未经测试的代码......警告讲师)
CXChildVisitResult attr_visit(CXCursor cursor, CXCursor parent, CXClientData data) {
if (clang_isAttribute(cursor)) {
*data = cursor;
return CXChildVisit_Break;
}
return CXChildVisit_Continue;
}
CXCursor first_attr(const CXCursor& c) {
CXCursor attr;
unsigned visit_result = clang_visitChildren(c, attr_visit, &attr);
if (!visit_result) // attribute not found
attr = clang_getNullCursor();
return attr;
}
至于查找游标a
代表哪个特定属性,结果clang_getCursorKind(a)
可以提供帮助,但唯一暴露的属性是:
CXCursor_IBActionAttr
CXCursor_IBOutletAttr
CXCursor_IBOutletCollectionAttr
CXCursor_CXXFinalAttr
CXCursor_CXXOverrideAttr
CXCursor_AnnotateAttr
CXCursor_AsmLabelAttr
其他一切都将是一个CXCursor_UnexposedAttr
,我能想到的获得它的文本的唯一方法是检查clang_getCursorExtent(a)
(即,阅读源代码;参见clang_tokenize
)。在注释的情况下,使用的特定注释可通过clang_getCursorDisplayName
.