aboutsummaryrefslogtreecommitdiff
path: root/clang/docs
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2018-11-12 08:38:10 +0000
committerHans Wennborg <hans@hanshq.net>2018-11-12 08:38:10 +0000
commit96a7860f7917a3568b63e25813ff2079d5a39e93 (patch)
tree516035fb6c89d9987081d04847adcf8e7fe2eec6 /clang/docs
parent8443f881bff8a9148702db7ce4248a80b9541bd5 (diff)
clang-cl: Add documentation for /Zc:dllexportInlines-
Differential revision: https://reviews.llvm.org/D54319 llvm-svn: 346639
Diffstat (limited to 'clang/docs')
-rw-r--r--clang/docs/UsersManual.rst76
1 files changed, 76 insertions, 0 deletions
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 87a6d3e0025d..a7f2f8145e87 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -2947,6 +2947,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
/Yc<filename> Generate a pch file for all code up to and including <filename>
/Yu<filename> Load a pch file and use it instead of all code up to and including <filename>
/Z7 Enable CodeView debug information in object files
+ /Zc:dllexportInlines- Don't dllexport/import inline member functions of dllexport/import classes
+ /Zc:dllexportInlines dllexport/import inline member functions of dllexport/import classes (default)
/Zc:sizedDealloc- Disable C++14 sized global deallocation functions
/Zc:sizedDealloc Enable C++14 sized global deallocation functions
/Zc:strictStrings Treat string literals as const
@@ -3096,6 +3098,80 @@ driver. Regardless of where they appear in the command line, the ``/clang:``
arguments are treated as if they were passed at the end of the clang-cl command
line.
+The /Zc:dllexportInlines- Option
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This causes the class-level `dllexport` and `dllimport` attributes not to be
+applied to inline member functions, as they otherwise would. For example, in
+the code below `S::foo()` would normally be defined and exported by the DLL,
+but when using the ``/Zc:dllexportInlines-`` flag it is not:
+
+.. code-block:: c
+
+ struct __declspec(dllexport) S {
+ void foo() {}
+ }
+
+This has the benefit that the compiler doesn't need to emit a definition of
+`S::foo()` in every translation unit where the declaration is included, as it
+would otherwise do to ensure there's a definition in the DLL even if it's not
+used there. If the declaration occurs in a header file that's widely used, this
+can save significant compilation time and output size. It also reduces the
+number of functions exported by the DLL similarly to what
+``-fvisibility-inlines-hidden`` does for shared objects on ELF and Mach-O.
+Since the function declaration comes with an inline definition, users of the
+library can use that definition directly instead of importing it from the DLL.
+
+Note that the Microsoft Visual C++ compiler does not support this option, and
+if code in a DLL is compiled with ``/Zc:dllexportInlines-``, the code using the
+DLL must be compiled in the same way so that it doesn't attempt to dllimport
+the inline member functions. The reverse scenario should generally work though:
+a DLL compiled without this flag (such as a system library compiled with Visual
+C++) can be referenced from code compiled using the flag, meaning that the
+referencing code will use the inline definitions instead of importing them from
+the DLL.
+
+Also note that like when using ``-fvisibility-inlines-hidden``, the address of
+`S::foo()` will be different inside and outside the DLL, breaking the C/C++
+standard requirement that functions have a unique address.
+
+The flag does not apply to explicit class template instantiation definitions or
+declarations, as those are typically used to explicitly provide a single
+definition in a DLL, (dllexported instantiation definition) or to signal that
+the definition is available elsewhere (dllimport instantiation declaration). It
+also doesn't apply to inline members with static local variables, to ensure
+that the same instance of the variable is used inside and outside the DLL.
+
+Using this flag can cause problems when inline functions that would otherwise
+be dllexported refer to internal symbols of a DLL. For example:
+
+.. code-block:: c
+
+ void internal();
+
+ struct __declspec(dllimport) S {
+ void foo() { internal(); }
+ }
+
+Normally, references to `S::foo()` would use the definition in the DLL from
+which it was exported, and which presumably also has the definition of
+`internal()`. However, when using ``/Zc:dllexportInlines-``, the inline
+definition of `S::foo()` is used directly, resulting in a link error since
+`internal()` is not available. Even worse, if there is an inline definition of
+`internal()` containing a static local variable, we will now refer to a
+different instance of that variable than in the DLL:
+
+.. code-block:: c
+
+ inline int internal() { static int x; return x++; }
+
+ struct __declspec(dllimport) S {
+ int foo() { return internal(); }
+ }
+
+This could lead to very subtle bugs. Using ``-fvisibility-inlines-hidden`` can
+lead to the same issue.
+
The /fallback Option
^^^^^^^^^^^^^^^^^^^^