With a couple of very minor modifications, recent versions of clang will 
support thread_local storage including support for complex destructors on 
10.6.8 using the same emutls.c system that gcc uses to support it. I'll attach 
the (amazingly simple) patches below. It picks up the emutls.c support from 
libgcc and libstdc++:

$ nm  /opt/local/lib/libgcc/libstdc++.6.dylib | grep cxa_thread
0000000000001e16 T ___cxa_thread_atexit

$ nm /opt/local/lib/libgcc/libgcc_s.1.dylib | grep emu
000000000000bd56 T ___emutls_get_address
000000000000bec7 T ___emutls_register_common


This works when we use the MacPorts alternate c++11 support Marcus came up 
with, using

-stdlib=macports-libstdc++

and it seems to me to pass all the tests of how thread_local should work that I 
can throw at it. So this seems very usable to me at present.




However, when using libc++ (my preferred setup) I'm still having a couple of 
issues getting cxa_thread_atexit and emutls_get_address to build into libc++abi 
and show up at runtime.

Using RJVB's libcxx Port, I have built libc++abi more in the LINUX way, with 
cxa_thread_atexit.cpp included (that was fairly easy), but it doesn't find the 
symbols in 

/opt/local/libexec/llvm-7.0/lib/clang/7.0.0/lib/darwin/libclang_rt.osx.a

that it needs to find and dies at runtime. I think it's possibly a visibility 
thing.

If there is anyone out there with any skills and interest in working on this 
please speak up and I'll bring you fully up to speed offline regarding my 
libc++/libc++abi build efforts

Best,

Ken


Patches for llvm/clang-7.0 to enable thread_local support using 
-stdlib=macports-libstdc++:

==========================
--- a/include/llvm/ADT/Triple.h.orig    2018-10-02 17:38:10.000000000 -0700
+++ b/include/llvm/ADT/Triple.h 2018-10-02 17:38:58.000000000 -0700
@@ -682,7 +682,7 @@
 
   /// Tests whether the target uses emulated TLS as default.
   bool hasDefaultEmulatedTLS() const {
-    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
+    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment() || 
isMacOSXVersionLT(10, 7);
   }
 
   /// @}
==========================
--- a/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp.orig    2018-10-02 
18:31:17.000000000 -0700
+++ b/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp 2018-10-02 18:32:35.000000000 
-0700
@@ -2255,7 +2255,7 @@
   const char *Name = "__cxa_atexit";
   if (TLS) {
     const llvm::Triple &T = CGF.getTarget().getTriple();
-    Name = T.isOSDarwin() ?  "_tlv_atexit" : "__cxa_thread_atexit";
+    Name = (T.isOSDarwin() && !T.isMacOSXVersionLT(10, 7)) ?  "_tlv_atexit" : 
"__cxa_thread_atexit";
   }
 
   // We're assuming that the destructor function is something we can
--- a/tools/clang/lib/Basic/Targets/OSTargets.h.orig    2018-10-02 
17:14:10.000000000 -0700
+++ b/tools/clang/lib/Basic/Targets/OSTargets.h 2018-10-02 17:14:41.000000000 
-0700
@@ -93,7 +93,7 @@
     this->TLSSupported = false;
 
     if (Triple.isMacOSX())
-      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
+      this->TLSSupported = !Triple.isMacOSXVersionLT(10, 4);
     else if (Triple.isiOS()) {
       // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
       // 32-bit simulator from 10 onwards.
==========================

Reply via email to