extending clang C-API (CIndex)

hi there,

I am about to work on extending the C-API provided by CIndex and friends
so I can introspect the AST and (especially) all the xyzDecl (from
python-ctypes.)

not everything can be readily exposed but, for what is easy to do, I was
thinking of exposing the methods of the Decls like so:

/*
* \brief Whether this class has a definition
*/
CINDEX_LINKAGE unsigned clang_CXXRecordDecl_hasDefinition(CXCursor C);

unsigned clang_CXXRecordDecl_hasDefinition(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;
  CXXRecordDecl *D =
  dyn_cast<CXXRecordDecl>(cxcursor::getCursorDecl(C));
  return (D && D->hasDefinition()) ? 1 : 0;
}

so the convention would be:

clang_[C++class-name]_[method-name]( cursor )

what do you think ?

cheers,
sebastien.

What is the point of such a mapping ? Why not use the C++ API itself ?

The warning I received on this list about using the C++ API directly was that the (existing) C API was much more stable than the C++ API.
I don't think this stability is related to the language (C vs. C++), but is caused by the the C++ API being much richer (and thus, no-one is willing to commit to any form of backward compatibility just yet).

If you propose such a one-to-one mapping, it seems your proposed C API will be no more stable than the C++ API. Why would anyone use that ?

(Note that I'm looking into mapping the existing AST (C++) API to my Synopsis ASG (Python) API (http://synopsis.fresco.org), using the current 2.7 release. I'm aware of this changing, but would hope that until the next major release it may be useful nonetheless.)

Thanks,
         Stefan

Stefan,

> hi there,
>
> I am about to work on extending the C-API provided by CIndex and friends
> so I can introspect the AST and (especially) all the xyzDecl (from
> python-ctypes.)
>
>
>

> so the convention would be:
>
> clang_[C++class-name]_[method-name]( cursor )
>
>
> what do you think ?
>

[...]

If you propose such a one-to-one mapping, it seems your proposed C API
will be no more stable than the C++ API. Why would anyone use that ?

the lingua franca beeing C, this extended C-api could be the basis for
bindings other than the python-ctypes ones.
every language out there has some kind FFI based on C.

I considered using the C++ API and the CPython one, but it felt like
work duplication wrt doing the same, extending directly libclang.
now, granted that some automation could be leveraged (swig,
gccxml+whatever) but that's an external dependency which I feel is
unnecessary.

cheers,
sebastien.

While designing the C API in libclang, we should be careful to only expose important functionality that is unlikely to change, and should strive to avoid introducing redundant functions. We want the C API to be clean and stable. In your example:

  - CXXRecordDecl and RecordDecl should share the same cursor kind and have the same operations in the C API: we'll use dynamic checking to determine when we're dealing with a C struct/union that never has certain attributes (e.g., base classes).

  - hasDefinition() is a shortcut for getting the definition of the current cursor, then checking whether the definition cursor is the same as the original cursor. This works for all cursor kinds, while clang_CXXRecordDecl_hasDefinition() would only work for C++ classes, structs, and unions.

I think it's great to make the C API more full-featured, but let's try to keep it minimal and full-featured.

  - Doug