<div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>I don't necessarily want to redirect you from this course of action; pragmatically-speaking, the attribute you're proposing seems very reasonable to me, and is probably the right short-to-medium-term solution. However:</div><div><br></div><div>It seems to me there are two different compilations that we need to care about:</div><div><br></div><div> 1) the compilation of the DSO itself</div><div> 2) the compilation of a user of the DSO</div><div><br></div><div>For (1), we would need to use a compiler that can force-emit the vtable, ideally without emitting all inline functions in the class. (If it emits too much, we do have ways to prevent the extra symbols being part of the DSO's ABI, but it's not ideal.) Any version of GCC can do that (via "inline template"), and if we add a standard or vendor-specific feature to clang to emit the type info, then recent Clang can do that too. Older Clang and other compilers will be left emitting too many symbols, which is likely tolerable, because the result should still be correct and building a new libc++ DSO with an old Clang is likely something we can discourage.</div></div></div></blockquote><div>It may be inadvisable anyway to link against a DSO build that is not widely distributed; however, binaries linked against a DSO build that exports too much will not load against "proper" DSO builds.<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div><br></div><div>For (2), it's my understanding that we do not /need/ to prevent users of libc++ from emitting their own copies of symbols that are also in the DSO. If we don't have a way of saying "the vtable is emitted in the DSO" for a particular compiler, the cost is that we may emit an unnecessary but mostly harmless copy of the vtable in the client program, not that we will miscompile or create an ABI problem.</div><div><br></div><div>So I think it might still be viable to switch libc++ entirely to per-function explicit instantiations, even before we have ubiquitous compiler support to deal with the result. But it's probably worth delaying that until such compiler features are at least broadly available, since there will be some costs (notably, code size) to compilers for which we cannot declare that class type info is available externally.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div>Unless there are serious concerns with the attribute, I’d like to solicit feedback on the following points:</div><div><br></div><div><div>- What entities does it make sense to apply this attribute to? Currently, I'm thinking only static and non-static member functions of templates, for lack of imagination and other use cases. Does it make sense to apply it to static data members? To the vtable and RTTI somehow?</div></div></div></div></blockquote><div><br></div><div>I would expect the attribute to be applicable to all members of templated classes that would be explicitly instantiated by an explicit instantiation of the enclosing class ([temp.explicit]p10),. That would be member functions (static or non-static), member classes (to suppress recursion into their members), and static data members.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div><div>- What other attributes would be mutually exclusive with this one? Right now I can only think of `internal_linkage`, but is there anything else?</div></div></div></div></blockquote><div><br></div><div>I don't think internal linkage needs to be mutually-exclusive with this attribute. I would expect that an internal_linkage + no_extern_template function would simply be unaffected by 'extern template', so would still be implicitly instantiated if referenced in a context where a definition is needed.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div>Thanks,</div><div>Louis</div><br><blockquote type="cite"><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"> <br><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div>Also, it’s not a huge reason not to do it, but that would constitute a very large change in libc++, which does everything opt-out right now. Comparatively, everything is already in place for libc++ to start using an hypothetical no_extern_template attribute, and in fact the patch that does that is like 4 lines. Of course, my search for the right solution is not primarily motivated by that.</div><div><br></div><div>I think I will start by exploring Reid’s idea of checking for incompatible visibilities using a visitor, and if that doesn’t take me anywhere, I’ll reconsider your suggestion. Independently, I’ll draft a C++ proposal to control where RTTI/vtables are instantiated and see where that idea goes.</div><div><br></div><div>Louis</div><div><br></div><br><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><div class="gmail_quote"><div><br class="m_-2454506149787444146m_399335037117398794gmail-m_8602693362901822949gmail-Apple-interchange-newline"></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">- What entities does it make sense to apply this attribute to? Currently, I'm thinking only static and non-static member functions of templates, for lack of imagination and other use cases. Does it make sense to apply it to static data members? To the vtable and RTTI somehow?<br><br>- What other attributes would be mutually exclusive with this one? Right now I can only think of `internal_linkage`, but is there anything else?<br><br>Finally, I'd also welcome any guidance on how to best achieve this in Clang. So far, I've achieved something that "works" by forcing declarations with `GVA_AvailableExternally` linkage to have `GVA_DiscardableODR` linkage (in `adjustGVALinkageForAttributes`). I think this is probably the wrong approach but I’m a Clang beginner, so I’m looking for advice if somebody has some. I'll soon publish an early code review on Phabricator to ease the process of getting feedback on the code itself.<br><br>Thanks,<br>Louis<br><br>[1]:<span class="m_-2454506149787444146m_399335037117398794gmail-m_8602693362901822949Apple-converted-space"> </span><a href="http://lists.llvm.org/pipermail/cfe-dev/2018-July/058460.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/cfe-dev/2018-July/058460.html</a><br>[2]:<span class="m_-2454506149787444146m_399335037117398794gmail-m_8602693362901822949Apple-converted-space"> </span><a href="http://lists.llvm.org/pipermail/cfe-dev/2018-July/058419.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/cfe-dev/2018-July/058419.html</a><br><br>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></blockquote></div></div></div></blockquote></div><br></div>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br></blockquote></div></div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none;float:none;display:inline!important">_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none;float:none;display:inline!important">cfe-dev mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><a href="mailto:cfe-dev@lists.llvm.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">cfe-dev@lists.llvm.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></blockquote></div></div></blockquote></div><br></div>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>