frutiger updated this revision to Diff 114640.
frutiger added a comment.

Add test cases for `__declspec(thread)` and static TLS.  Clean up formatting to 
adhere to the project style.


https://reviews.llvm.org/D37577

Files:
  bindings/python/clang/cindex.py
  bindings/python/tests/cindex/test_tls_kind.py
  include/clang-c/Index.h
  tools/libclang/CIndex.cpp
  tools/libclang/libclang.exports

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
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<VarDecl>(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: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -2836,6 +2836,20 @@
  */
 CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
 
+/**
+ * \brief Describe the "TLS kind" of the declaration referred to by a cursor.
+ */
+enum CXTLSKind {
+  CXTLS_None = 0,
+  CXTLS_Dynamic,
+  CXTLS_Static
+};
+
+/**
+ * \brief Determine the "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: bindings/python/tests/cindex/test_tls_kind.py
===================================================================
--- /dev/null
+++ bindings/python/tests/cindex/test_tls_kind.py
@@ -0,0 +1,36 @@
+
+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 linkage specifers 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.
+    tu = get_tu("""
+__declspec(thread) int tls_declspec;
+""", lang = 'cpp', flags=['-fms-extensions', '-target', 'amd64-win32'])
+
+    tls_declspec = get_cursor(tu.cursor, 'tls_declspec')
+    assert tls_declspec.tls_kind == TLSKind.STATIC
+
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 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 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',
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to