IRgen/C++: When mark vtables used, make sure to still append to the VTableUse array if we promote a vtable from being just used to having its definition required. This ensures that we properly inform the consumer about whether the vtable is required or not, previously we could fail to do so when the vtable was in the VTableUses array before the decl which marked it as required.

- I think this can be cleaned up, since this means we may notify the consumer about the vtable twice, but I didn't see an easy fix for this without more substantial refactoring.
 - Doug, please review!

llvm-svn: 104577
This commit is contained in:
Daniel Dunbar 2010-05-25 00:33:13 +00:00
parent 105ce6db87
commit 532177685a
2 changed files with 24 additions and 3 deletions

View File

@ -6085,8 +6085,15 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
std::pair<llvm::DenseMap<CXXRecordDecl *, bool>::iterator, bool>
Pos = VTablesUsed.insert(std::make_pair(Class, DefinitionRequired));
if (!Pos.second) {
Pos.first->second = Pos.first->second || DefinitionRequired;
return;
// If we already had an entry, check to see if we are promoting this vtable
// to required a definition. If so, we need to reappend to the VTableUses
// list, since we may have already processed the first entry.
if (DefinitionRequired && !Pos.first->second) {
Pos.first->second = true;
} else {
// Otherwise, we can early exit.
return;
}
}
// Local classes need to have their virtual members marked

View File

@ -160,4 +160,18 @@ void use_F(F<char> &fc) {
// CHECK-12: @_ZTSN12_GLOBAL__N_11AE = internal constant
// CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal constant
// RUN: FileCheck --check-prefix=CHECK-G %s < %t
//
// CHECK-G: @_ZTV1GIiE = weak_odr constant
template <typename T>
class G {
public:
G() {}
virtual void f0();
virtual void f1();
};
template <>
void G<int>::f1() {}
template <typename T>
void G<T>::f0() {}
void G_f0() { new G<int>(); }