[llvm-bugs] [Bug 33628] New: Implement a new dllexport/dllimport variant that doesn't apply to class inline functions

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Jun 28 10:35:05 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=33628

            Bug ID: 33628
           Summary: Implement a new dllexport/dllimport variant that
                    doesn't apply to class inline functions
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: rnk at google.com
                CC: llvm-bugs at lists.llvm.org

Exporting all inline functions of a class with many inline functions can be
very expensive because they will appear in every object file that includes the
header. Here's an example of what this looks like:

$ cat t.cpp
struct __declspec(dllexport) Foo {
  void f() {}
  void g() {}
};

$ cl -c t.cpp && llvm-nm t.obj
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

t.cpp
00000000 T ??4Foo@@QEAAAEAU0@$$QEAU0@@Z
00000000 T ??4Foo@@QEAAAEAU0 at AEBU0@@Z
00000000 T ?f at Foo@@QEAAXXZ
00000000 T ?g at Foo@@QEAAXXZ
01055e97 a @comp.id
80000190 a @feat.00

t.cpp doesn't have to reference Foo or it's inline functions in any way to get
all of these symbols, so Foo's inline functions will be emitted in every file
that uses its header. This is necessary for ABI compatibility with MSVC, so we
can't change our behavior here.

Other platforms that use visibility have the similar but different problem that
deduplicating default visibility inline functions at runtime is expensive. One
solution is to use -fvisibility-inlines-hidden, which compromises the C++
language guarantee that function addresses are unique across the whole program.
This flag is fairly widely used, which suggests this is a reasonable compromise
for many users.

I don't think we want a flag to control this behavior for dllexport, because it
would be totally ABI incompatible with MSVC. So, instead, I propose that we add
a new attribute that only applies to classes, and has the semantics that it
doesn't propagate to inline methods. We could call this
dll(export|import)_noninline.

I think our heuristic for applying dllexport should only rely on the contents
of the class body. This means that methods that are declared inline after the
end of the class body will be exported. The user can suppress this behavior by
adding the 'inline' keyword to the in-class declaration. Here's what this looks
like:

struct __declspec(dllexport_noninline) Foo { void f(); };
inline void Foo::f() {} // will be exported, we thought it was not inline

struct __declspec(dllexport_noninline) Bar { inline void f(); };
inline void Bar::f() {} // will NOT be exported, we knew it was inline at class
end

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170628/c95e684f/attachment.html>


More information about the llvm-bugs mailing list