[LLVMdev] r72619

Eric Christopher echristo at apple.com
Fri Dec 4 14:40:52 PST 2009

> Only "_Z11dummysymbolv" should be there. Here's Doug's explanation of  
> why this should be so:
> Here's what it *looks* like is happening, and where the FE is probably  
> getting it wrong. First of all, the constructor in question is defined  
> outside of the basic_string class template as a non-inline definition:
>   template<typename _CharT, typename _Traits, typename _Alloc>
>     basic_string<_CharT, _Traits, _Alloc>::
>     basic_string(const _CharT* __s, const _Alloc& __a)
> Second, there is an explicit template instantiation declaration:
>     extern template class basic_string<char>;
> That extern template instantiation declaration is supposed to suppress  
> the implicit instantiation of non-inline member functions like that  
> basic_string constructor. I had tripped over something similar to this  
> previously, where the SL llvm-gcc was suppressing instantiation of all  
> member functions of basic_string<char> (including inline ones, which  
> would be a performance problem). So, there was clearly a change in  
> this area.
> Here's my guess: We're not properly suppressing the implicit  
> instantiation of non-inline member functions defined out-of-line.  
> Thus, we're instantiating that basic_string constructor when we  
> shouldn't be. That instantiation then forces the implicit  
> instantiation of _S_construct<const char*>. Since _S_construct is a  
> member template, it's instantiation is *not* suppressed (despite being  
> in basic_string<char>), so we emit it as a weak definition.
> I don't have a debug llvm-gcc available to see why this might be  
> happening. The logic to suppress instantiation based on an extern  
> template is in instantiate_decl (gcc/cp/pt.c):
>   /* Check to see whether we know that this template will be
>      instantiated in some other file, as with "extern template"
>      extension.  */
>   external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
>   /* In general, we do not instantiate such templates...  */
>   if (external_p
>       /* ... but we instantiate inline functions so that we can inline
>          them and ... */
>       && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
>       /* ... we instantiate static data members whose values are
>          needed in integral constant expressions.  */
>       && ! (TREE_CODE (d) == VAR_DECL
>     goto out;
> For the basic_string constructor, if we don't take that "goto",  
> something is wrong. If we do take that "goto", my guess is wrong. I  
> don't have a recent debug llvm-gcc to validate my guess.

So, on top of this it seems like a lot of the semantics have changed after your patch. I'm certain the existing patch is wrong and that we'll want a computation somewhat similar to the clang one that I think Doug is going to post.

I think the safe thing is to revert for now and we can discuss all of the semantics and what's going on in a more leisurely fashion and let poor Bill get his project building :)


More information about the llvm-dev mailing list