11

次の例で、クラス メンバー関数の一般化された属性を解析したいと思います。

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

foolibclang C API を使用して、ソース内のと(および属性があるbarことを知ってfooいる)を区別したいと思います。interestingこれは可能ですか?API で使用されている概念を説明する例やドキュメントを見つけるのに苦労しています (参考文献を見つけましたが、概念が説明されていない場合は使いにくいです)。

4

2 に答える 2

8

AST で一般化された属性を見つけることができませんでしたが (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()"
  }
}

tooと同じ出力を生成しvoid foo INTERESTING ();ます。

于 2013-11-13T08:50:52.857 に答える
2

次のfirst_attr関数のようなものは、渡されたカーソルの最初の属性のカーソルが存在する場合はそれをフェッチし、存在しない場合は null カーソルをフェッチします (テストされていないコード... 注意事項)

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

于 2013-10-31T16:43:03.463 に答える