Index: bindings/python/clang/cindex.py =================================================================== --- bindings/python/clang/cindex.py +++ bindings/python/clang/cindex.py @@ -1548,6 +1548,14 @@ return self._loc + @property + def tls_kind(self): + """Return the thread-local storage (TLS) kind of this cursor.""" + if not hasattr(self, '_tls_kind'): + self._tls_kind = conf.lib.clang_getCursorTLSKind(self) + + return TLSKind.from_id(self._tls_kind) + @property def extent(self): """ @@ -2061,6 +2069,23 @@ RefQualifierKind.LVALUE = RefQualifierKind(1) RefQualifierKind.RVALUE = RefQualifierKind(2) +class TLSKind(BaseEnumeration): + """Describes the kind of thread-local storage (TLS) of a cursor.""" + + # The unique kind objects, indexed by id. + _kinds = [] + _name_map = None + + def from_param(self): + return self.value + + def __repr__(self): + return 'TLSKind.%s' % (self.name,) + +TLSKind.NONE = TLSKind(0) +TLSKind.DYNAMIC = TLSKind(1) +TLSKind.STATIC = TLSKind(2) + class Type(Structure): """ The type of an element in the abstract syntax tree. @@ -4066,6 +4091,7 @@ 'Index', 'SourceLocation', 'SourceRange', + 'TLSKind', 'TokenKind', 'Token', 'TranslationUnitLoadError', Index: bindings/python/tests/cindex/test_tls_kind.py =================================================================== --- /dev/null +++ bindings/python/tests/cindex/test_tls_kind.py @@ -0,0 +1,37 @@ + +from clang.cindex import TLSKind +from clang.cindex import Cursor +from clang.cindex import TranslationUnit + +from .util import get_cursor +from .util import get_tu + +def test_tls_kind(): + """Ensure that thread-local storage kinds are available on cursors.""" + + tu = get_tu(""" +int tls_none; +thread_local int tls_dynamic; +_Thread_local int tls_static; +""", lang = 'cpp') + + tls_none = get_cursor(tu.cursor, 'tls_none') + assert tls_none.tls_kind == TLSKind.NONE; + + tls_dynamic = get_cursor(tu.cursor, 'tls_dynamic') + assert tls_dynamic.tls_kind == TLSKind.DYNAMIC + + tls_static = get_cursor(tu.cursor, 'tls_static') + assert tls_static.tls_kind == TLSKind.STATIC + + # The following case tests '__declspec(thread)'. Since it is a Microsoft + # specific extension, specific flags are required for the parser to pick + # these up. + flags = ['-fms-extensions', '-target', 'x86_64-unknown-windows-win32'] + tu = get_tu(""" +__declspec(thread) int tls_declspec; +""", lang = 'cpp', flags=flags) + + tls_declspec = get_cursor(tu.cursor, 'tls_declspec') + assert tls_declspec.tls_kind == TLSKind.STATIC + Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -2836,6 +2836,22 @@ */ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); +/** + * \brief Describe the "thread-local storage (TLS) kind" of the declaration + * referred to by a cursor. + */ +enum CXTLSKind { + CXTLS_None = 0, + CXTLS_Dynamic, + CXTLS_Static +}; + +/** + * \brief Determine the "thread-local storage (TLS) kind" of the declaration + * referred to by a cursor. + */ +CINDEX_LINKAGE enum CXTLSKind clang_getCursorTLSKind(CXCursor cursor); + /** * \brief Returns the translation unit that a cursor originated from. */ Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -7412,6 +7412,22 @@ return CXLanguage_Invalid; } +CXTLSKind clang_getCursorTLSKind(CXCursor cursor) { + const Decl *D = cxcursor::getCursorDecl(cursor); + if (const VarDecl *VD = dyn_cast(D)) { + switch (VD->getTLSKind()) { + case VarDecl::TLS_None: + return CXTLS_None; + case VarDecl::TLS_Dynamic: + return CXTLS_Dynamic; + case VarDecl::TLS_Static: + return CXTLS_Static; + } + } + + return CXTLS_None; +} + /// \brief If the given cursor is the "templated" declaration /// descibing a class or function template, return the class or /// function template. Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -189,6 +189,7 @@ clang_getCursorResultType clang_getCursorSemanticParent clang_getCursorSpelling +clang_getCursorTLSKind clang_getCursorType clang_getCursorUSR clang_getCursorVisibility