[cfe-commits] r132331 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/vtable-instantiation.cc
Nick Lewycky
nicholas at mxc.ca
Tue May 31 00:58:42 PDT 2011
Author: nicholas
Date: Tue May 31 02:58:42 2011
New Revision: 132331
URL: http://llvm.org/viewvc/llvm-project?rev=132331&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/vtable-instantiation.cc
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=132331&r1=132330&r2=132331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue May 31 02:58:42 2011
@@ -4658,7 +4658,7 @@
/// types, static variables, enumerators, etc.
std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
- bool PerformPendingInstantiations(bool LocalOnly = false);
+ void PerformPendingInstantiations(bool LocalOnly = false);
TypeSourceInfo *SubstType(TypeSourceInfo *T,
const MultiLevelTemplateArgumentList &TemplateArgs,
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=132331&r1=132330&r2=132331&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue May 31 02:58:42 2011
@@ -378,30 +378,22 @@
}
}
- bool SomethingChanged;
- do {
- SomethingChanged = false;
-
- // If DefinedUsedVTables ends up marking any virtual member functions it
- // might lead to more pending template instantiations, which we then need
- // to instantiate.
- if (DefineUsedVTables())
- SomethingChanged = true;
-
- // C++: Perform implicit template instantiations.
- //
- // FIXME: When we perform these implicit instantiations, we do not
- // carefully keep track of the point of instantiation (C++ [temp.point]).
- // This means that name lookup that occurs within the template
- // instantiation will always happen at the end of the translation unit,
- // so it will find some names that should not be found. Although this is
- // common behavior for C++ compilers, it is technically wrong. In the
- // future, we either need to be able to filter the results of name lookup
- // or we need to perform template instantiations earlier.
- if (PerformPendingInstantiations())
- SomethingChanged = true;
-
- } while (SomethingChanged);
+ // If DefinedUsedVTables ends up marking any virtual member functions it
+ // might lead to more pending template instantiations, which we then need
+ // to instantiate.
+ DefineUsedVTables();
+
+ // C++: Perform implicit template instantiations.
+ //
+ // FIXME: When we perform these implicit instantiations, we do not
+ // carefully keep track of the point of instantiation (C++ [temp.point]).
+ // This means that name lookup that occurs within the template
+ // instantiation will always happen at the end of the translation unit,
+ // so it will find some names that should not be found. Although this is
+ // common behavior for C++ compilers, it is technically wrong. In the
+ // future, we either need to be able to filter the results of name lookup
+ // or we need to perform template instantiations earlier.
+ PerformPendingInstantiations();
}
// Remove file scoped decls that turned out to be used.
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=132331&r1=132330&r2=132331&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue May 31 02:58:42 2011
@@ -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,
Modified: cfe/trunk/test/SemaCXX/vtable-instantiation.cc
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vtable-instantiation.cc?rev=132331&r1=132330&r2=132331&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vtable-instantiation.cc (original)
+++ cfe/trunk/test/SemaCXX/vtable-instantiation.cc Tue May 31 02:58:42 2011
@@ -1,21 +1,22 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// PR8640
-template<class T1> struct C1 {
- virtual void c1() {
- T1 t1 = 3; // expected-error {{cannot initialize a variable}}
- }
-};
+namespace PR8640 {
+ template<class T1> struct C1 {
+ virtual void c1() {
+ T1 t1 = 3; // expected-error {{cannot initialize a variable}}
+ }
+ };
-template<class T2> struct C2 {
- void c2() {
- new C1<T2>(); // expected-note {{in instantiation of member function}}
- }
-};
+ template<class T2> struct C2 {
+ void c2() {
+ new C1<T2>(); // expected-note {{in instantiation of member function}}
+ }
+ };
-void f() {
- C2<int*> c2;
- c2.c2(); // expected-note {{in instantiation of member function}}
+ void f() {
+ C2<int*> c2;
+ c2.c2(); // expected-note {{in instantiation of member function}}
+ }
}
namespace PR9325 {
@@ -42,5 +43,26 @@
{
Target<int*>* traits = &Provider<int*>::Instance;
}
+}
+namespace PR10020 {
+ struct MG {
+ virtual void Accept(int) = 0;
+ };
+
+ template <typename Type>
+ struct GMG : MG {
+ void Accept(int i) {
+ static_cast<Type *>(0)->Accept(i); // expected-error{{member reference base}}
+ }
+ static GMG* Method() { return &singleton; } // expected-note{{in instantiation of}}
+ static GMG singleton;
+ };
+
+ template <typename Type>
+ GMG<Type> GMG<Type>::singleton;
+
+ void test(void) {
+ GMG<int>::Method(); // expected-note{{in instantiation of}}
+ }
}
More information about the cfe-commits
mailing list