[libcxx-dev] dllimport vs inline methods in MSVC mode/clang-cl

Nico Weber via libcxx-dev libcxx-dev at lists.llvm.org
Mon Nov 2 05:58:27 PST 2020


I think this is basically https://bugs.llvm.org/show_bug.cgi?id=41018 ,
which just needs fixing.

Building libc++ with dllexportInlines- might also work (
https://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html
).

On Mon, Nov 2, 2020 at 8:26 AM Martin Storsjö via libcxx-dev <
libcxx-dev at lists.llvm.org> wrote:

> Hi,
>
> I'm looking into an issue with how dllimport of classes/methods works when
> operating in MSVC mode (i.e. building with clang-cl).
>
> Methods that aren't supposed to be part of the ABI interface are marked
> with _LIBCPP_INLINE_VISIBILITY (expanding to __attribute__
> ((__exclude_from_explicit_instantiation__)), or potentially __attribute__
> ((__always_inline__))).
>
> When the whole class is marked dllimport, clang doesn't seem to react to
> these attributes at all.
>
> This is a big practical problem for the method
> std::filesystem::path::u8string. The method is marked with
> _LIBCPP_INLINE_VISIBILITY, but ends up exported/imported nevertheless.
>
> In C++17, this method returns a basic_string<char>, while in C++20 it
> returns a basic_string<char8_t>. With itanium name mangling, the return
> type of a method isn't included in the signature, but with MSVC C++ name
> mangling, the two versions of the method are distinctly different.
>
> So despite the best efforts, a DLL build of the library exports the
> function u8string (with whichever return type it had when the lib was
> built), and a caller that is built with a different language version will
> fail to link as it tries to import the symbol from the DLL.
>
> A small testcase of the issue looks like this:
>
>
> extern "C" void externFunc(void *ptr);
>
> class __declspec(dllimport) MyClass {
> public:
>      void inline
>      __attribute__ ((__always_inline__))
>      __attribute__ ((__exclude_from_explicit_instantiation__))
>      inlineFunc() {
>          externFunc(this);
>      }
> };
>
> void caller(MyClass *obj) {
>     obj->inlineFunc();
> }
>
>
> When building an object file out of this, it ends up with an extern call
> to __imp_<decoration>inlineFunc. (The rules for dllexport/import are
> different in mingw mode, where it ends up behaving as hoped/intended.)
>
> Is there any way around this, to mark that we really, really, want to
> inline any call to this method, despite being in a dllimported class?
>
> // Martin
>
> _______________________________________________
> libcxx-dev mailing list
> libcxx-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/libcxx-dev/attachments/20201102/df3853bb/attachment.html>


More information about the libcxx-dev mailing list