diff options
author | David Chisnall <csdavec@swan.ac.uk> | 2010-11-03 14:12:26 +0000 |
---|---|---|
committer | David Chisnall <csdavec@swan.ac.uk> | 2010-11-03 14:12:26 +0000 |
commit | 3387c65a094a02b2a94c05111d035a97d3d5c794 (patch) | |
tree | 3411833f7bed52b36f0cead45f91468c1ed69e8e | |
parent | 96ede778620c7296a332eb1bba7cc6a19141bd7c (diff) |
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
-rw-r--r-- | include/clang-c/Index.h | 23 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 35 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 1 |
3 files changed, 59 insertions, 0 deletions
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<NamedDecl>(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 |