diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 218b37707d52ac20e5077032d58835134b83922a..37072a765824427fc22937aa9aa0d5a7f3757be7 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -2377,6 +2377,38 @@ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); */ CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor); + +/** + * \brief A fast container representing a set of CXCursors. + */ +typedef struct CXCursorSetImpl *CXCursorSet; + +/** + * \brief Creates an empty CXCursorSet. + */ +CINDEX_LINKAGE CXCursorSet clang_createCXCursorSet(void); + +/** + * \brief Disposes a CXCursorSet and releases its associated memory. + */ +CINDEX_LINKAGE void clang_disposeCXCursorSet(CXCursorSet cset); + +/** + * \brief Queries a CXCursorSet to see if it contains a specific CXCursor. + * + * \returns non-zero if the set contains the specified cursor. +*/ +CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset, + CXCursor cursor); + +/** + * \brief Inserts a CXCursor into a CXCursorSet. + * + * \returns zero if the CXCursor was already in the set, and non-zero otherwise. +*/ +CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset, + CXCursor cursor); + /** * \brief Determine the semantic parent of the given cursor. * diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index f494d96be4c8c7ed1a24f12d40553137f6460286..b5682055b9e3851c7af918e2eae6e62c081575ad 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -997,6 +997,72 @@ CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) { return clang_getNullCursor(); } +} // end: extern "C" + +//===----------------------------------------------------------------------===// +// CXCursorSet. +//===----------------------------------------------------------------------===// + +typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl; + +static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) { + return (CXCursorSet) setImpl; +} +static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) { + return (CXCursorSet_Impl*) set; +} +namespace llvm { +template<> struct DenseMapInfo<CXCursor> { +public: + static inline CXCursor getEmptyKey() { + return MakeCXCursorInvalid(CXCursor_InvalidFile); + } + static inline CXCursor getTombstoneKey() { + return MakeCXCursorInvalid(CXCursor_NoDeclFound); + } + static inline unsigned getHashValue(const CXCursor &cursor) { + return llvm::DenseMapInfo<std::pair<const void *, const void *> > + ::getHashValue(std::make_pair(cursor.data[0], cursor.data[1])); + } + static inline bool isEqual(const CXCursor &x, const CXCursor &y) { + return x.kind == y.kind && + x.data[0] == y.data[0] && + x.data[1] == y.data[1]; + } +}; +} + +extern "C" { +CXCursorSet clang_createCXCursorSet() { + return packCXCursorSet(new CXCursorSet_Impl()); +} + +void clang_disposeCXCursorSet(CXCursorSet set) { + delete unpackCXCursorSet(set); +} + +unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) { + CXCursorSet_Impl *setImpl = unpackCXCursorSet(set); + if (!setImpl) + return 0; + return setImpl->find(cursor) == setImpl->end(); +} + +unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) { + // Do not insert invalid cursors into the set. + if (cursor.kind >= CXCursor_FirstInvalid && + cursor.kind <= CXCursor_LastInvalid) + return 1; + + CXCursorSet_Impl *setImpl = unpackCXCursorSet(set); + if (!setImpl) + return 1; + unsigned &entry = (*setImpl)[cursor]; + unsigned flag = entry == 0 ? 1 : 0; + entry = 1; + return flag; +} + CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { enum CXCursorKind kind = clang_getCursorKind(cursor); if (clang_isDeclaration(kind)) { diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 3fe8378a8b2f478a2233970a7e22d076e08fe25b..c7508bc5449becee2348bd9cb64665cd12b4c578 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -1,3 +1,5 @@ +clang_CXCursorSet_contains +clang_CXCursorSet_insert clang_CXIndex_getGlobalOptions clang_CXIndex_setGlobalOptions clang_CXXMethod_isStatic @@ -77,6 +79,7 @@ clang_constructUSR_ObjCIvar clang_constructUSR_ObjCMethod clang_constructUSR_ObjCProperty clang_constructUSR_ObjCProtocol +clang_createCXCursorSet clang_createIndex clang_createTranslationUnit clang_createTranslationUnitFromSourceFile @@ -85,6 +88,7 @@ clang_defaultDiagnosticDisplayOptions clang_defaultEditingTranslationUnitOptions clang_defaultReparseOptions clang_defaultSaveOptions +clang_disposeCXCursorSet clang_disposeCXTUResourceUsage clang_disposeCodeCompleteResults clang_disposeDiagnostic