Closed efriedma-quic closed 14 years ago
Never mind, it's fixed in SVN. Thanks, Anders!
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.
Committed revision 90753.
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
struct A { virtual int a(T x); }; template int A ::a(T x) { return x; } A a() { return new A ; } void b() { return 1; } //template<> int A ::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).
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
It's extremely nasty, but if libstdc++ depends on it, I don't really see an alternative.
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.
The standard gives us a lot of leeway there. If we want, we can instantiate virtual members the moment the containing class is instantiated.
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.
Extended Description
Testcase: template struct A {
A();
virtual int a(T x);
};
template A::A() {}
template int A::a(T x) { return *x; }
A x;
int main() { return 0; }
Output (clang x.cpp -fno-rtti): /tmp/cc-nJeNb1.o:(.gnu.linkonce.r._ZTV1AIiE+0x8): undefined reference to `A::a()'
collect2: ld returned 1 exit status
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Compare to output from g++: /tmp/x.cpp: In member function ‘int A::a(T) [with T = int]’:
/tmp/x.cpp:10: instantiated from here
/tmp/x.cpp:8: error: invalid type argument of ‘unary *’