LibClang-3.8.0: cbits/visitors.c
#include <stdlib.h>
#include "visitors.h"
#define INITIAL_LIST_CAPACITY 16
#define LIST_GROWTH_RATE 4
typedef struct
{
CXCursor* items;
unsigned count;
size_t capacity;
} CursorList;
void freeCursorList(CXCursor* cursors)
{
free(cursors);
}
#define LIST_INIT(_type) { \
malloc(INITIAL_LIST_CAPACITY * sizeof(_type)), \
0, \
INITIAL_LIST_CAPACITY \
}
#define LIST_APPEND(_type, _list, _item) \
do { \
if (_list->count >= _list->capacity) { \
size_t newCapacity = LIST_GROWTH_RATE * _list->capacity; \
_list->items = \
realloc(_list->items, newCapacity * sizeof(_type)); \
_list->capacity = newCapacity; \
} \
\
_list->items[_list->count++] = _item; \
} while(0) \
enum CXChildVisitResult childListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
CursorList* childList = (CursorList*) clientData;
LIST_APPEND(CXCursor, childList, cursor);
return CXChildVisit_Continue;
}
void getChildren(CXCursor parent, CXCursor** childrenOut, unsigned* countOut)
{
CursorList childList = LIST_INIT(CXCursor);
clang_visitChildren(parent, childListBuilder, &childList);
*childrenOut = childList.items;
*countOut = childList.count;
}
enum CXChildVisitResult descendantListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
CursorList* childList = (CursorList*) clientData;
LIST_APPEND(CXCursor, childList, cursor);
return CXChildVisit_Recurse;
}
void getDescendants(CXCursor parent, CXCursor** childrenOut, unsigned* countOut)
{
CursorList childList = LIST_INIT(CXCursor);
clang_visitChildren(parent, descendantListBuilder, &childList);
*childrenOut = childList.items;
*countOut = childList.count;
}
enum CXChildVisitResult declarationListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
if (clang_isDeclaration(clang_getCursorKind(cursor))) {
CursorList* childList = (CursorList*) clientData;
LIST_APPEND(CXCursor, childList, cursor);
}
return CXChildVisit_Recurse;
}
void getDeclarations(CXTranslationUnit tu, CXCursor** childrenOut, unsigned* countOut)
{
CursorList childList = LIST_INIT(CXCursor);
CXCursor parent = clang_getTranslationUnitCursor(tu);
clang_visitChildren(parent, declarationListBuilder, &childList);
*childrenOut = childList.items;
*countOut = childList.count;
}
enum CXChildVisitResult referenceListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
if (clang_isReference(clang_getCursorKind(cursor))) {
CursorList* childList = (CursorList*) clientData;
LIST_APPEND(CXCursor, childList, cursor);
}
return CXChildVisit_Recurse;
}
void getReferences(CXTranslationUnit tu, CXCursor** childrenOut, unsigned* countOut)
{
CursorList childList = LIST_INIT(CXCursor);
CXCursor parent = clang_getTranslationUnitCursor(tu);
clang_visitChildren(parent, referenceListBuilder, &childList);
*childrenOut = childList.items;
*countOut = childList.count;
}
typedef struct
{
CursorList decls;
CursorList refs;
} CursorListPair;
enum CXChildVisitResult declAndRefListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
CursorListPair* declsAndRefs = (CursorListPair*) clientData;
if (clang_isDeclaration(clang_getCursorKind(cursor))) {
CursorList* decls = &declsAndRefs->decls;
LIST_APPEND(CXCursor, decls, cursor);
}
if (clang_isReference(clang_getCursorKind(cursor))) {
CursorList* refs = &declsAndRefs->refs;
LIST_APPEND(CXCursor, refs, cursor);
}
return CXChildVisit_Recurse;
}
void getDeclarationsAndReferences(CXTranslationUnit tu,
CXCursor** declsOut,
unsigned* declCountOut,
CXCursor** refsOut,
unsigned* refCountOut)
{
CursorListPair declsAndRefs = {
LIST_INIT(CXCursor),
LIST_INIT(CXCursor)
};
CXCursor parent = clang_getTranslationUnitCursor(tu);
clang_visitChildren(parent, declAndRefListBuilder, &declsAndRefs);
*declsOut = declsAndRefs.decls.items;
*declCountOut = declsAndRefs.decls.count;
*refsOut = declsAndRefs.refs.items;
*refCountOut = declsAndRefs.refs.count;
}
typedef struct
{
ParentedCursor* items;
unsigned count;
size_t capacity;
} ParentedCursorList;
void freeParentedCursorList(ParentedCursor* parentedCursors)
{
free(parentedCursors);
}
enum CXChildVisitResult parentedDescendantListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
ParentedCursorList* descendantList = (ParentedCursorList*) clientData;
ParentedCursor newEntry = {
parent,
cursor
};
LIST_APPEND(ParentedCursor, descendantList, newEntry);
return CXChildVisit_Recurse;
}
void getParentedDescendants(CXCursor parent, ParentedCursor** descendantsOut,
unsigned* countOut)
{
ParentedCursorList descendantList = LIST_INIT(ParentedCursor);
clang_visitChildren(parent, parentedDescendantListBuilder, &descendantList);
*descendantsOut = descendantList.items;
*countOut = descendantList.count;
}
enum CXChildVisitResult parentedDeclarationListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
ParentedCursorList* declarationList = (ParentedCursorList*) clientData;
if (clang_isDeclaration(clang_getCursorKind(cursor))) {
ParentedCursor newEntry = {
parent,
cursor
};
LIST_APPEND(ParentedCursor, declarationList, newEntry);
}
return CXChildVisit_Recurse;
}
void getParentedDeclarations(CXTranslationUnit tu, ParentedCursor** declarationsOut,
unsigned* countOut)
{
ParentedCursorList declarationList = LIST_INIT(ParentedCursor);
CXCursor parent = clang_getTranslationUnitCursor(tu);
clang_visitChildren(parent, parentedDeclarationListBuilder, &declarationList);
*declarationsOut = declarationList.items;
*countOut = declarationList.count;
}
enum CXChildVisitResult parentedReferenceListBuilder(CXCursor cursor, CXCursor parent,
CXClientData clientData)
{
ParentedCursorList* referenceList = (ParentedCursorList*) clientData;
if (clang_isReference(clang_getCursorKind(cursor))) {
ParentedCursor newEntry = {
parent,
cursor
};
LIST_APPEND(ParentedCursor, referenceList, newEntry);
}
return CXChildVisit_Recurse;
}
void getParentedReferences(CXTranslationUnit tu, ParentedCursor** referencesOut,
unsigned* countOut)
{
ParentedCursorList referenceList = LIST_INIT(ParentedCursor);
CXCursor parent = clang_getTranslationUnitCursor(tu);
clang_visitChildren(parent, parentedReferenceListBuilder, &referenceList);
*referencesOut = referenceList.items;
*countOut = referenceList.count;
}
typedef struct
{
ParentedCursorList decls;
ParentedCursorList refs;
} ParentedCursorListPair;
enum CXChildVisitResult parentedDeclAndRefListBuilder(CXCursor cursor,
CXCursor parent,
CXClientData clientData)
{
ParentedCursorListPair* declsAndRefs = (ParentedCursorListPair*) clientData;
if (clang_isDeclaration(clang_getCursorKind(cursor))) {
ParentedCursor newEntry = {
parent,
cursor
};
ParentedCursorList* decls = &declsAndRefs->decls;
LIST_APPEND(ParentedCursor, decls, newEntry);
}
if (clang_isReference(clang_getCursorKind(cursor))) {
ParentedCursor newEntry = {
parent,
cursor
};
ParentedCursorList* refs = &declsAndRefs->refs;
LIST_APPEND(ParentedCursor, refs, newEntry);
}
return CXChildVisit_Recurse;
}
void getParentedDeclarationsAndReferences(CXTranslationUnit tu,
ParentedCursor** declsOut,
unsigned* declCountOut,
ParentedCursor** refsOut,
unsigned* refCountOut)
{
ParentedCursorListPair declsAndRefs = {
LIST_INIT(ParentedCursor),
LIST_INIT(ParentedCursor)
};
CXCursor parent = clang_getTranslationUnitCursor(tu);
clang_visitChildren(parent, parentedDeclAndRefListBuilder, &declsAndRefs);
*declsOut = declsAndRefs.decls.items;
*declCountOut = declsAndRefs.decls.count;
*refsOut = declsAndRefs.refs.items;
*refCountOut = declsAndRefs.refs.count;
}
typedef struct
{
Inclusion* items;
unsigned count;
size_t capacity;
} InclusionList;
void freeInclusionList(Inclusion* inclusions)
{
free(inclusions);
}
void inclusionListBuilder(CXFile includedFile, CXSourceLocation* inclusionStack,
unsigned stackLen, CXClientData clientData)
{
// Skip the initial file.
if (stackLen == 0)
return;
InclusionList* inclusionList = (InclusionList*) clientData;
Inclusion newEntry = {
includedFile,
inclusionStack[0],
stackLen == 1 // It's a direct inclusion if there's only one stack entry.
};
LIST_APPEND(Inclusion, inclusionList, newEntry);
}
void getInclusions(CXTranslationUnit tu, Inclusion** inclusionsOut,
unsigned* countOut)
{
InclusionList inclusionList = LIST_INIT(Inclusion);
clang_getInclusions(tu, inclusionListBuilder, &inclusionList);
*inclusionsOut = inclusionList.items;
*countOut = inclusionList.count;
}