summaryrefslogtreecommitdiff
path: root/docs/DesignDocs
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:58 +0000
commit53a420fba21cf1644972b34dcd811a43cdb8368d (patch)
tree66a19f6f8b65215772549a51d688492ab8addc0d /docs/DesignDocs
parentb50f1549701eb950921e5d6f2e55ba1a1dadbb43 (diff)
Notes
Diffstat (limited to 'docs/DesignDocs')
-rw-r--r--docs/DesignDocs/DebugMode.rst100
-rw-r--r--docs/DesignDocs/VisibilityMacros.rst127
2 files changed, 227 insertions, 0 deletions
diff --git a/docs/DesignDocs/DebugMode.rst b/docs/DesignDocs/DebugMode.rst
new file mode 100644
index 000000000000..166c733e6630
--- /dev/null
+++ b/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/docs/DesignDocs/VisibilityMacros.rst b/docs/DesignDocs/VisibilityMacros.rst
new file mode 100644
index 000000000000..2ee07142d85c
--- /dev/null
+++ b/docs/DesignDocs/VisibilityMacros.rst
@@ -0,0 +1,127 @@
+========================
+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_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 and vtable as having default visibility.
+ `_LIBCPP_TYPE_VIS`. This macro has no effect on the visibility of the
+ type's member functions. This attribute cannot be used on class templates.
+
+ **GCC Behavior**: GCC does not support Clang's `type_visibility(...)`
+ attribute. With GCC the `visibility(...)` attribute is used and member
+ functions are affected.
+
+**_LIBCPP_TYPE_VIS_ONLY**
+ The same as `_LIBCPP_TYPE_VIS` except that it may be applied to templates.
+
+ **Windows Behavior**: DLLs do not support dllimport/export on class templates.
+ The macro has an empty definition on this platform.
+
+ Note: This macro should be renamed `_LIBCPP_TEMPLATE_TYPE_VIS`.
+
+**_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_TYPE_VIS_ONLY` 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_TYPE_VIS_ONLY` is the same as `_LIBCPP_TYPE_VIS` the
+ visibility is already correct. The macro has an empty definition with GCC.
+
+ **Windows Behavior**: `extern template` and `dllexport` are fundamentally
+ incompatible *on a template class* on Windows; the former suppresses
+ instantiation, while the latter forces it. Specifying both on the same
+ declaration makes the template class 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 template *classes*. Extern template *functions* obey
+ regular import/export semantics, and applying `dllexport` directly to the
+ extern template declaration 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 template class 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_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>`_