Closed Quuxplusone closed 14 years ago
We need to instantiate the virtual functions of an implicitly-instantiated class template specialization (or member class thereof) when we're going to emit a vtable. Right now, that decision is made by CodeGen, but we'll need to boost it up into Sema so that we can make sure that all of the virtual functions will get instantiated when CodeGen is going to need them.
The standard gives us a lot of leeway there. If we want, we can instantiate virtual members the moment the containing class is instantiated.
Attached instantiate-virtual.cpp
(369 bytes, text/plain): Test case that illustrates the specialization-after-instantiation problem
I tried implementing that approach, where we instantiate virtual member functions along with the class itself, but I was running into specialization-after-instantiation errors in libstdc++. See the attached patch and test case.
I think we'll need to figure out what GCC does and mimic that.
Attached virtual-function-instantiation-fail.patch
(3035 bytes, text/plain): Failed attempt at instantiating virtual member functions with the class
(In reply to comment #5)
> I think we'll need to figure out what GCC does and mimic that.
I believe what gcc does is that at the end of file, for any templated class, it
checks whether the vtable is needed; if it is, it defines the vtable and
instantiates the functions referred to by the vtable. As proof, note that for
the following testcase, the instantiation error comes *after* the error about
b(), even though there isn't anything interesting in the file after it:
template <class T> struct A {
virtual int a(T x);
};
template<class T> int A<T>::a(T x) { return *x; }
A<int>* a() { return new A<int>; }
void b() { return 1; }
//template<> int A<int>::a(int x) { return 2; }
It's extremely nasty, but if libstdc++ depends on it, I don't really see an
alternative.
(In reply to comment #6)
> (In reply to comment #5)
> > I think we'll need to figure out what GCC does and mimic that.
>
> I believe what gcc does is that at the end of file, for any templated class,
it
> checks whether the vtable is needed; if it is, it defines the vtable and
> instantiates the functions referred to by the vtable. As proof, note that for
> the following testcase, the instantiation error comes *after* the error about
> b(), even though there isn't anything interesting in the file after it:
> template <class T> struct A {
> virtual int a(T x);
> };
> template<class T> int A<T>::a(T x) { return *x; }
> A<int>* a() { return new A<int>; }
> void b() { return 1; }
> //template<> int A<int>::a(int x) { return 2; }
>
> It's extremely nasty, but if libstdc++ depends on it, I don't really see an
> alternative.
FWIW, GCC (and Clang, and EDG) instantiate functions at the end of the
translation unit regardless of where the actual point of instantiation was.
It's possible that the synthesis of the definition of the default constructor
is also being delayed until the end of the file and that, in turn, forces the
instantiation of the non-pure virtuals in the class (because a vtable is
needed).
Committed revision 90753.
I don't know... I still get link errors related to the std::basic_istream class. I don't know if this is a separate issue or what, but std::basic_istream still isn't getting instantiated properly.
Never mind, it's fixed in SVN. Thanks, Anders!
virtual-function-instantiation-fail.patch
(3035 bytes, text/plain)instantiate-virtual.cpp
(369 bytes, text/plain)