Whenever we instantiate a static data member, make sure to define any new
vtables! Fixes PR10020
This also allows us to revert the part of r130023 which added a big loop around
the template instantiation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132331 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index bf1e499..adf9b2f 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2481,9 +2481,13 @@
PerformPendingInstantiations();
// Restore the set of pending vtables.
+ assert(VTableUses.empty() &&
+ "VTableUses should be empty before it is discarded.");
VTableUses.swap(SavedVTableUses);
// Restore the set of pending implicit instantiations.
+ assert(PendingInstantiations.empty() &&
+ "PendingInstantiations should be empty before it is discarded.");
PendingInstantiations.swap(SavedPendingInstantiations);
}
}
@@ -2557,9 +2561,12 @@
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
+ llvm::SmallVector<VTableUse, 16> SavedVTableUses;
std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
- if (Recursive)
+ if (Recursive) {
+ VTableUses.swap(SavedVTableUses);
PendingInstantiations.swap(SavedPendingInstantiations);
+ }
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
@@ -2581,11 +2588,23 @@
}
if (Recursive) {
+ // Define any newly required vtables.
+ DefineUsedVTables();
+
// Instantiate any pending implicit instantiations found during the
// instantiation of this template.
PerformPendingInstantiations();
+ // Restore the set of pending vtables.
+ assert(VTableUses.empty() &&
+ "VTableUses should be empty before it is discarded, "
+ "while instantiating static data member.");
+ VTableUses.swap(SavedVTableUses);
+
// Restore the set of pending implicit instantiations.
+ assert(PendingInstantiations.empty() &&
+ "PendingInstantiations should be empty before it is discarded, "
+ "while instantiating static data member.");
PendingInstantiations.swap(SavedPendingInstantiations);
}
}
@@ -3181,10 +3200,7 @@
/// \brief Performs template instantiation for all implicit template
/// instantiations we have seen until this point.
-///
-/// \returns true if anything was instantiated.
-bool Sema::PerformPendingInstantiations(bool LocalOnly) {
- bool InstantiatedAnything = false;
+void Sema::PerformPendingInstantiations(bool LocalOnly) {
while (!PendingLocalImplicitInstantiations.empty() ||
(!LocalOnly && !PendingInstantiations.empty())) {
PendingImplicitInstantiation Inst;
@@ -3205,7 +3221,6 @@
TSK_ExplicitInstantiationDefinition;
InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true,
DefinitionRequired);
- InstantiatedAnything = true;
continue;
}
@@ -3242,10 +3257,7 @@
TSK_ExplicitInstantiationDefinition;
InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true,
DefinitionRequired);
- InstantiatedAnything = true;
}
-
- return InstantiatedAnything;
}
void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,