[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