【问题标题】:Inspecting generalized attributes with libclang使用 libclang 检查通用属性
【发布时间】:2013-11-08 08:17:00
【问题描述】:

我想在下面的例子中解析类成员函数的泛化属性:

class Foo
{
public:
    void foo [[interesting]] ();
    void bar ();
};

使用libclang C API,我想在源代码中区分foobar(并且知道foo 具有interesting 属性)。这可能吗?我很难找到解释 API 中使用的概念的示例或文档(我找到了一个参考资料,但如果没有解释这些概念,这有点难以使用)。

【问题讨论】:

    标签: c++ clang abstract-syntax-tree libclang


    【解决方案1】:

    虽然我无法在 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 (); 相同的输出。

    【讨论】:

      【解决方案2】:

      类似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获得。

      【讨论】:

      • 我尝试使用 python 绑定来制作代码原型,但该属性在 AST 中根本不可见(甚至不是未公开的属性)。当我添加 noreturn 属性时,它确实出现在我的 AST 转储中。
      猜你喜欢
      • 2013-10-05
      • 2018-01-18
      • 2014-05-24
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多