Search code examples
c++clangabstract-syntax-treelibclang

Inspecting generalized attributes with libclang


I would like to parse generalized attributes of class member functions in the following example:

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

Using the libclang C API, I would like to distinguish between foo and bar (and know that foo has the interesting attribute) in the source. Is this possible? I have a hard time finding examples or documentation that explains the concepts used in the API (I've found a reference, but that's kind of hard to use when the concepts are not explained).


Solution

  • While I was unable to find the generalized attributes in the AST (it seems they are dropped when or before constructing the AST, not after it), I did find a workaround.

    There is an annotate clang attribute in the following form:

    __attribute__((annotate("something")))
    

    With a macro I could get a reasonable syntax and an annotation which is visible in the AST:

    #define INTERESTING __attribute__((annotate("interesting")))
    
    class Foo
    {
    public:
        INTERESTING void foo();
        void bar();
    };
    

    The attribute will be the child of the method node, with its display_name being the annotation string. A possible AST dump:

     <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()"
      }
    }
    

    It produces the same output with void foo INTERESTING (); too.