[cfe-dev] Adding a new attribute: no_extern_template
Reid Kleckner via cfe-dev
cfe-dev at lists.llvm.org
Tue Aug 21 15:48:30 PDT 2018
On Tue, Aug 21, 2018 at 2:44 PM Louis Dionne via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> I've been looking to add an attribute (tentatively called
> no_extern_template) which would prevent member functions in a template from
> getting available_externally linkage even when there is a matching extern
> template declaration. In other words, given the following code:
>
The entire point of extern template declarations is to be able to emit
member functions with available_externally linkage, so this seems like a
pretty strange feature.
Is the original problem limited to the __init pattern (below), or are is
needed for more than that?
template <class T>
struct Foo {
inline __attribute__((visibility("hidden")))
int __init(int x) { /* LOTS OF CODE */ }
inline __attribute__((visibility("default")))
int bar(int x) { return __init(x); }
};
My first idea (probably too simple to work and already rejected) is to mark
bar noinline. Then it will be available_externally, but not inlineable.
After CodeGen, we will have a call to the bar definition provided by the
libc++ DSO, and there will not be link errors. If that doesn't work, read
on.
We had a very similar to a problem with dllimport, which also uses
available_externally. This is the situation:
#if BUILDING_FOO
#define FOO_EXPORT __declspec(dllexport)
#else
#define FOO_EXPORT __declspec(dllimport)
#endif
struct Foo {
void bar();
void FOO_EXPORT foo() { bar(); }
};
When compiling the code that uses Foo, BUILDING_FOO is not defined, and
dllimport is used. However, Foo::foo calls Foo::bar, which is not exported,
and so the link will fail if foo() is emitted available_externally and
inlined. In this case, we found that we couldn't actually emit
available_externally definitions of foo, we just had to call the
out-of-line version provided by the DLL. See the
class DLLImportFunctionVisitor in CodeGenModule.cpp that implements this.
It's not bulletproof, but it works well enough.
I think we might want to consider implementing the same kind of traversal
to check for visibility conflicts (a default visibility function calls a
hidden one) before emitting available_externally functions for an extern
template declaration.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180821/263dc4eb/attachment.html>
More information about the cfe-dev
mailing list