From: Saleem Abdulrasool Date: Wed, 13 Sep 2017 02:15:09 +0000 (+0000) Subject: libclang: expose `clang_getCursorTLSKind` X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=420a3ebdcee02758222bc4a11351e3a4083e6922;p=clang libclang: expose `clang_getCursorTLSKind` Introduce the 'TLS Kind' property of variable declarations through libclang. Additionally, provide a Python accessor for it, and test that functionality. Patch by Masud Rahman! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313111 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index 4069ab8650..3eb2d70504 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -1548,6 +1548,14 @@ class Cursor(Structure): 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.NONE = RefQualifierKind(0) 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 @@ __all__ = [ 'Index', 'SourceLocation', 'SourceRange', + 'TLSKind', 'TokenKind', 'Token', 'TranslationUnitLoadError', diff --git a/bindings/python/tests/cindex/test_tls_kind.py b/bindings/python/tests/cindex/test_tls_kind.py new file mode 100644 index 0000000000..6a03c0d5ee --- /dev/null +++ b/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 + diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 0b0d160bf3..b5d994783f 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -2836,6 +2836,22 @@ enum CXLanguageKind { */ 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. */ diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index ed4f263945..6d120bcab4 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -7412,6 +7412,22 @@ CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { 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. diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index e0d178a529..62a233ebec 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -189,6 +189,7 @@ clang_getCursorReferenced clang_getCursorResultType clang_getCursorSemanticParent clang_getCursorSpelling +clang_getCursorTLSKind clang_getCursorType clang_getCursorUSR clang_getCursorVisibility