diff options
Diffstat (limited to 'lib/libcxx/docs/DesignDocs')
-rw-r--r-- | lib/libcxx/docs/DesignDocs/AvailabilityMarkup.rst | 114 | ||||
-rw-r--r-- | lib/libcxx/docs/DesignDocs/DebugMode.rst | 100 | ||||
-rw-r--r-- | lib/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst | 79 | ||||
-rw-r--r-- | lib/libcxx/docs/DesignDocs/VisibilityMacros.rst | 163 |
4 files changed, 456 insertions, 0 deletions
diff --git a/lib/libcxx/docs/DesignDocs/AvailabilityMarkup.rst b/lib/libcxx/docs/DesignDocs/AvailabilityMarkup.rst new file mode 100644 index 00000000000..4a85c698f23 --- /dev/null +++ b/lib/libcxx/docs/DesignDocs/AvailabilityMarkup.rst @@ -0,0 +1,114 @@ +=================== +Availability Markup +=================== + +.. contents:: + :local: + +Overview +======== + +Libc++ is used as a system library on macOS and iOS (amongst others). In order +for users to be able to compile a binary that is intended to be deployed to an +older version of the platform, clang provides the +`availability attribute <https://clang.llvm.org/docs/AttributeReference.html#availability>`_ +that can be placed on declarations to describe the lifecycle of a symbol in the +library. + +Design +====== + +When a new feature is introduced that requires dylib support, a macro should be +created in include/__config to mark this feature as unavailable for all the +systems. For example:: + + // Define availability macros. + #if defined(_LIBCPP_USE_AVAILABILITY_APPLE) + #define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) + #else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR) + #define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) + #else + #define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS + #endif + +When the library is updated by the platform vendor, the markup can be updated. +For example:: + + #define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) + +In the source code, the macro can be added on a class if the full class requires +type info from the library for example:: + + _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL + class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access + : public std::logic_error { + +or on a particular symbol: + + _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; + + +Testing +======= + +Some parameters can be passed to lit to run the test-suite and exercising the +availability. + +* The `platform` parameter controls the deployement target. For example lit can + be invoked with `--param=platform=macosx10.8`. Default is the current host. +* The `use_system_cxx_lib` parameter indicates to use another library than the + just built one. Invoking lit with `--param=use_system_cxx_lib=true` will run + the test-suite against the host system library. Alternatively a path to the + directory containing a specific prebuilt libc++ can be used, for example: + `--param=use_system_cxx_lib=/path/to/macOS/10.8/`. +* The `with_availability` boolean parameter enables the availability markup. + +Tests can be marked as XFAIL based on multiple features made available by lit: + + +* if either `use_system_cxx_lib` or `with_availability` is passed to lit, + assuming `--param=platform=macosx10.8` is passed as well the following + features will be available: + + - availability + - availability=x86_64 + - availability=macosx + - availability=x86_64-macosx + - availability=x86_64-apple-macosx10.8 + - availability=macosx10.8 + + This feature is used to XFAIL a test that *is* using a class of a method marked + as unavailable *and* that is expected to *fail* if deployed on an older system. + +* if `use_system_cxx_lib` is passed to lit, the following features will also + be available: + + - with_system_cxx_lib + - with_system_cxx_lib=x86_64 + - with_system_cxx_lib=macosx + - with_system_cxx_lib=x86_64-macosx + - with_system_cxx_lib=x86_64-apple-macosx10.8 + - with_system_cxx_lib=macosx10.8 + + This feature is used to XFAIL a test that is *not* using a class of a method + marked as unavailable *but* that is expected to fail if deployed on an older + system. For example if we know that it exhibits a but in the libc on a + particular system version. + +* if `with_availability` is passed to lit, the following features will also + be available: + + - availability_markup + - availability_markup=x86_64 + - availability_markup=macosx + - availability_markup=x86_64-macosx + - availability_markup=x86_64-apple-macosx10.8 + - availability_markup=macosx10.8 + + This feature is used to XFAIL a test that *is* using a class of a method + marked as unavailable *but* that is expected to *pass* if deployed on an older + system. For example if it is using a symbol in a statically evaluated context. diff --git a/lib/libcxx/docs/DesignDocs/DebugMode.rst b/lib/libcxx/docs/DesignDocs/DebugMode.rst new file mode 100644 index 00000000000..3b997d44607 --- /dev/null +++ b/lib/libcxx/docs/DesignDocs/DebugMode.rst @@ -0,0 +1,100 @@ +========== +Debug Mode +========== + +.. contents:: + :local: + +.. _using-debug-mode: + +Using Debug Mode +================ + +Libc++ provides a debug mode that enables assertions meant to detect incorrect +usage of the standard library. By default these assertions are disabled but +they can be enabled using the ``_LIBCPP_DEBUG`` macro. + +**_LIBCPP_DEBUG** Macro +----------------------- + +**_LIBCPP_DEBUG**: + This macro is used to enable assertions and iterator debugging checks within + libc++. By default it is undefined. + + **Values**: ``0``, ``1`` + + Defining ``_LIBCPP_DEBUG`` to ``0`` or greater enables most of libc++'s + assertions. Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging" + which provides additional assertions about the validity of iterators used by + the program. + + Note that this option has no effect on libc++'s ABI + +**_LIBCPP_DEBUG_USE_EXCEPTIONS**: + When this macro is defined ``_LIBCPP_ASSERT`` failures throw + ``__libcpp_debug_exception`` instead of aborting. Additionally this macro + disables exception specifications on functions containing ``_LIBCPP_ASSERT`` + checks. This allows assertion failures to correctly throw through these + functions. + +Handling Assertion Failures +--------------------------- + +When a debug assertion fails the assertion handler is called via the +``std::__libcpp_debug_function`` function pointer. It is possible to override +this function pointer using a different handler function. Libc++ provides two +different assertion handlers, the default handler +``std::__libcpp_abort_debug_handler`` which aborts the program, and +``std::__libcpp_throw_debug_handler`` which throws an instance of +``std::__libcpp_debug_exception``. Libc++ can be changed to use the throwing +assertion handler as follows: + +.. code-block:: cpp + + #define _LIBCPP_DEBUG 1 + #include <string> + int main() { + std::__libcpp_debug_function = std::__libcpp_throw_debug_function; + try { + std::string::iterator bad_it; + std::string str("hello world"); + str.insert(bad_it, '!'); // causes debug assertion + } catch (std::__libcpp_debug_exception const&) { + return EXIT_SUCCESS; + } + return EXIT_FAILURE; + } + +Debug Mode Checks +================= + +Libc++'s debug mode offers two levels of checking. The first enables various +precondition checks throughout libc++. The second additionally enables +"iterator debugging" which checks the validity of iterators used by the program. + +Basic Checks +============ + +These checks are enabled when ``_LIBCPP_DEBUG`` is defined to either 0 or 1. + +The following checks are enabled by ``_LIBCPP_DEBUG``: + + * FIXME: Update this list + +Iterator Debugging Checks +========================= + +These checks are enabled when ``_LIBCPP_DEBUG`` is defined to 1. + +The following containers and STL classes support iterator debugging: + + * ``std::string`` + * ``std::vector<T>`` (``T != bool``) + * ``std::list`` + * ``std::unordered_map`` + * ``std::unordered_multimap`` + * ``std::unordered_set`` + * ``std::unordered_multiset`` + +The remaining containers do not currently support iterator debugging. +Patches welcome. diff --git a/lib/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst b/lib/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst new file mode 100644 index 00000000000..556c45b7e1f --- /dev/null +++ b/lib/libcxx/docs/DesignDocs/ThreadingSupportAPI.rst @@ -0,0 +1,79 @@ +===================== +Threading Support API +===================== + +.. contents:: + :local: + +Overview +======== + +Libc++ supports using multiple different threading models and configurations +to implement the threading parts of libc++, including ``<thread>`` and ``<mutex>``. +These different models provide entirely different interfaces from each +other. To address this libc++ wraps the underlying threading API in a new and +consistent API, which it uses internally to implement threading primitives. + +The ``<__threading_support>`` header is where libc++ defines its internal +threading interface. It contains forward declarations of the internal threading +interface as well as definitions for the interface. + +External Threading API and the ``<__external_threading>`` header +================================================================ + +In order to support vendors with custom threading API's libc++ allows the +entire internal threading interface to be provided by an external, +vendor provided, header. + +When ``_LIBCPP_HAS_THREAD_API_EXTERNAL`` is defined the ``<__threading_support>`` +header simply forwards to the ``<__external_threading>`` header (which must exist). +It is expected that the ``<__external_threading>`` header provide the exact +interface normally provided by ``<__threading_support>``. + +External Threading Library +========================== + +libc++ can be compiled with its internal threading API delegating to an external +library. Such a configuration is useful for library vendors who wish to +distribute a thread-agnostic libc++ library, where the users of the library are +expected to provide the implementation of the libc++ internal threading API. + +On a production setting, this would be achieved through a custom +``<__external_threading>`` header, which declares the libc++ internal threading +API but leaves out the implementation. + +The ``-DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY`` option allows building libc++ in +such a configuration while allowing it to be tested on a platform that supports +any of the threading systems (e.g. pthread) supported in ``__threading_support`` +header. Therefore, the main purpose of this option is to allow testing of this +particular configuration of the library without being tied to a vendor-specific +threading system. This option is only meant to be used by libc++ library +developers. + +Threading Configuration Macros +============================== + +**_LIBCPP_HAS_NO_THREADS** + This macro is defined when libc++ is built without threading support. It + should not be manually defined by the user. + +**_LIBCPP_HAS_THREAD_API_EXTERNAL** + This macro is defined when libc++ should use the ``<__external_threading>`` + header to provide the internal threading API. This macro overrides + ``_LIBCPP_HAS_THREAD_API_PTHREAD``. + +**_LIBCPP_HAS_THREAD_API_PTHREAD** + This macro is defined when libc++ should use POSIX threads to implement the + internal threading API. + +**_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL** + This macro is defined when libc++ expects the definitions of the internal + threading API to be provided by an external library. When defined + ``<__threading_support>`` will only provide the forward declarations and + typedefs for the internal threading API. + +**_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL** + This macro is used to build an external threading library using the + ``<__threading_support>``. Specifically it exposes the threading API + definitions in ``<__threading_support>`` as non-inline definitions meant to + be compiled into a library. diff --git a/lib/libcxx/docs/DesignDocs/VisibilityMacros.rst b/lib/libcxx/docs/DesignDocs/VisibilityMacros.rst new file mode 100644 index 00000000000..993ce2cca5f --- /dev/null +++ b/lib/libcxx/docs/DesignDocs/VisibilityMacros.rst @@ -0,0 +1,163 @@ +======================== +Symbol Visibility Macros +======================== + +.. contents:: + :local: + +Overview +======== + +Libc++ uses various "visibility" macros in order to provide a stable ABI in +both the library and the headers. These macros work by changing the +visibility and inlining characteristics of the symbols they are applied to. + +Visibility Macros +================= + +**_LIBCPP_HIDDEN** + Mark a symbol as hidden so it will not be exported from shared libraries. + +**_LIBCPP_FUNC_VIS** + Mark a symbol as being exported by the libc++ library. This attribute must + be applied to the declaration of all functions exported by the libc++ dylib. + +**_LIBCPP_EXTERN_VIS** + Mark a symbol as being exported by the libc++ library. This attribute may + only be applied to objects defined in the libc++ library. On Windows this + macro applies `dllimport`/`dllexport` to the symbol. On all other platforms + this macro has no effect. + +**_LIBCPP_OVERRIDABLE_FUNC_VIS** + Mark a symbol as being exported by the libc++ library, but allow it to be + overridden locally. On non-Windows, this is equivalent to `_LIBCPP_FUNC_VIS`. + This macro is applied to all `operator new` and `operator delete` overloads. + + **Windows Behavior**: Any symbol marked `dllimport` cannot be overridden + locally, since `dllimport` indicates the symbol should be bound to a separate + DLL. All `operator new` and `operator delete` overloads are required to be + locally overridable, and therefore must not be marked `dllimport`. On Windows, + this macro therefore expands to `__declspec(dllexport)` when building the + library and has an empty definition otherwise. + +**_LIBCPP_INLINE_VISIBILITY** + Mark a function as hidden and force inlining whenever possible. + +**_LIBCPP_ALWAYS_INLINE** + A synonym for `_LIBCPP_INLINE_VISIBILITY` + +**_LIBCPP_TYPE_VIS** + Mark a type's typeinfo, vtable and members as having default visibility. + This attribute cannot be used on class templates. + +**_LIBCPP_TEMPLATE_VIS** + Mark a type's typeinfo and vtable as having default visibility. + This macro has no effect on the visibility of the type's member functions. + + **GCC Behavior**: GCC does not support Clang's `type_visibility(...)` + attribute. With GCC the `visibility(...)` attribute is used and member + functions are affected. + + **Windows Behavior**: DLLs do not support dllimport/export on class templates. + The macro has an empty definition on this platform. + + +**_LIBCPP_ENUM_VIS** + Mark the typeinfo of an enum as having default visibility. This attribute + should be applied to all enum declarations. + + **Windows Behavior**: DLLs do not support importing or exporting enumeration + typeinfo. The macro has an empty definition on this platform. + + **GCC Behavior**: GCC un-hides the typeinfo for enumerations by default, even + if `-fvisibility=hidden` is specified. Additionally applying a visibility + attribute to an enum class results in a warning. The macro has an empty + definition with GCC. + +**_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS** + Mark the member functions, typeinfo, and vtable of the type named in + a `_LIBCPP_EXTERN_TEMPLATE` declaration as being exported by the libc++ library. + This attribute must be specified on all extern class template declarations. + + This macro is used to override the `_LIBCPP_TEMPLATE_VIS` attribute + specified on the primary template and to export the member functions produced + by the explicit instantiation in the dylib. + + **GCC Behavior**: GCC ignores visibility attributes applied the type in + extern template declarations and applying an attribute results in a warning. + However since `_LIBCPP_TEMPLATE_VIS` is the same as + `__attribute__((visibility("default"))` the visibility is already correct. + The macro has an empty definition with GCC. + + **Windows Behavior**: `extern template` and `dllexport` are fundamentally + incompatible *on a class template* on Windows; the former suppresses + instantiation, while the latter forces it. Specifying both on the same + declaration makes the class template be instantiated, which is not desirable + inside headers. This macro therefore expands to `dllimport` outside of libc++ + but nothing inside of it (rather than expanding to `dllexport`); instead, the + explicit instantiations themselves are marked as exported. Note that this + applies *only* to extern *class* templates. Extern *function* templates obey + regular import/export semantics, and applying `dllexport` directly to the + extern template declaration (i.e. using `_LIBCPP_FUNC_VIS`) is the correct + thing to do for them. + +**_LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS** + Mark the member functions, typeinfo, and vtable of an explicit instantiation + of a class template as being exported by the libc++ library. This attribute + must be specified on all class template explicit instantiations. + + It is only necessary to mark the explicit instantiation itself (as opposed to + the extern template declaration) as exported on Windows, as discussed above. + On all other platforms, this macro has an empty definition. + +**_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS** + Mark a symbol as hidden so it will not be exported from shared libraries. This + is intended specifically for method templates of either classes marked with + `_LIBCPP_TYPE_VIS` or classes with an extern template instantiation + declaration marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS`. + + When building libc++ with hidden visibility, we want explicit template + instantiations to export members, which is consistent with existing Windows + behavior. We also want classes annotated with `_LIBCPP_TYPE_VIS` to export + their members, which is again consistent with existing Windows behavior. + Both these changes are necessary for clients to be able to link against a + libc++ DSO built with hidden visibility without encountering missing symbols. + + An unfortunate side effect, however, is that method templates of classes + either marked `_LIBCPP_TYPE_VIS` or with extern template instantiation + declarations marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` also get default + visibility when instantiated. These methods are often implicitly instantiated + inside other libraries which use the libc++ headers, and will therefore end up + being exported from those libraries, since those implicit instantiations will + receive default visibility. This is not acceptable for libraries that wish to + control their visibility, and led to PR30642. + + Consequently, all such problematic method templates are explicitly marked + either hidden (via this macro) or inline, so that they don't leak into client + libraries. The problematic methods were found by running + `bad-visibility-finder <https://github.com/smeenai/bad-visibility-finder>`_ + against the libc++ headers after making `_LIBCPP_TYPE_VIS` and + `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility. + +**_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY** + Mark a member function of a class template as visible and always inline. This + macro should only be applied to member functions of class templates that are + externally instantiated. It is important that these symbols are not marked + as hidden as that will prevent the dylib definition from being found. + + This macro is used to maintain ABI compatibility for symbols that have been + historically exported by the libc++ library but are now marked inline. + +**_LIBCPP_EXCEPTION_ABI** + Mark the member functions, typeinfo, and vtable of the type as being exported + by the libc++ library. This macro must be applied to all *exception types*. + Exception types should be defined directly in namespace `std` and not the + versioning namespace. This allows throwing and catching some exception types + between libc++ and libstdc++. + +Links +===== + +* `[cfe-dev] Visibility in libc++ - 1 <http://lists.llvm.org/pipermail/cfe-dev/2013-July/030610.html>`_ +* `[cfe-dev] Visibility in libc++ - 2 <http://lists.llvm.org/pipermail/cfe-dev/2013-August/031195.html>`_ +* `[libcxx] Visibility fixes for Windows <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130805/085461.html>`_ |