From: David Chisnall Date: Wed, 3 Nov 2010 14:12:26 +0000 (+0000) Subject: Added cursor visitor that takes a block as an argument. Tested compiling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3387c65a094a02b2a94c05111d035a97d3d5c794;p=clang Added cursor visitor that takes a block as an argument. Tested compiling libclang with both clang -fblocks and gcc (no blocks support). Only exposed in the header to compilers that do have blocks support. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118170 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index bb76c564cc..20c8c11994 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1828,6 +1828,29 @@ typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor, CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data); +#ifdef __has_feature +# if __has_feature(blocks) +/** + * \brief Visitor invoked for each cursor found by a traversal. + * + * This visitor block will be invoked for each cursor found by + * clang_visitChildrenWithBlock(). Its first argument is the cursor being + * visited, its second argument is the parent visitor for that cursor. + * + * The visitor should return one of the \c CXChildVisitResult values + * to direct clang_visitChildrenWithBlock(). + */ +typedef enum CXChildVisitResult + (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); + +/** + * Visits the children of a cursor using the specified block. Behaves + * identically to clang_visitChildren() in all other respects. + */ +unsigned clang_visitChildrenWithBlock(CXCursor parent, + CXCursorVisitorBlock block); +# endif +#endif /** * @} diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index e07c25d77a..ac57a6941c 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2467,6 +2467,41 @@ unsigned clang_visitChildren(CXCursor parent, return CursorVis.VisitChildren(parent); } +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#if __has_feature(blocks) +typedef enum CXChildVisitResult + (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); + +static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, + CXClientData client_data) { + CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; + return block(cursor, parent); +} +#else +// If we are compiled with a compiler that doesn't have native blocks support, +// define and call the block manually, so the +typedef struct _CXChildVisitResult +{ + void *isa; + int flags; + int reserved; + enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor, CXCursor); +} *CXCursorVisitorBlock; + +static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, + CXClientData client_data) { + CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; + return block->invoke(block, cursor, parent); +} +#endif + + +unsigned clang_visitChildrenWithBlock(CXCursor parent, CXCursorVisitorBlock block) { + return clang_visitChildren(parent, visitWithBlock, block); +} + static CXString getDeclSpelling(Decl *D) { NamedDecl *ND = dyn_cast_or_null(D); if (!ND) diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 9935a584b9..fd96be35b2 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -113,3 +113,4 @@ clang_saveTranslationUnit clang_sortCodeCompletionResults clang_tokenize clang_visitChildren +clang_visitChildrenWithBlock