Something like the following first_attr function will fetch the cursor of the first attribute of the passed cursor if it exists, or a null cursor if it doesn't (untested code... caveat lector)
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;
}
As for finding which specific attribute a cursor a represents, the result of clang_getCursorKind(a) can help, but the only attributes exposed are:
CXCursor_IBActionAttr
CXCursor_IBOutletAttr
CXCursor_IBOutletCollectionAttr
CXCursor_CXXFinalAttr
CXCursor_CXXOverrideAttr
CXCursor_AnnotateAttr
CXCursor_AsmLabelAttr
Everything else will be a CXCursor_UnexposedAttr and the only way I can think of to get the text of it is to examine clang_getCursorExtent(a) (i.e., read the source code; cf. clang_tokenize). In the case of annotations, the specific annotation used is available through clang_getCursorDisplayName.