summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Sema/Sema.h18
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp10
-rw-r--r--clang/test/SemaTemplate/instantiate-local-class.cpp20
3 files changed, 42 insertions, 6 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 300619b3896..b635d9b271c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6406,6 +6406,24 @@ public:
/// types, static variables, enumerators, etc.
std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
+ class SavePendingLocalImplicitInstantiationsRAII {
+ public:
+ SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) {
+ SavedPendingLocalImplicitInstantiations.swap(
+ S.PendingLocalImplicitInstantiations);
+ }
+
+ ~SavePendingLocalImplicitInstantiationsRAII() {
+ SavedPendingLocalImplicitInstantiations.swap(
+ S.PendingLocalImplicitInstantiations);
+ }
+
+ private:
+ Sema &S;
+ std::deque<PendingImplicitInstantiation>
+ SavedPendingLocalImplicitInstantiations;
+ };
+
void PerformPendingInstantiations(bool LocalOnly = false);
TypeSourceInfo *SubstType(TypeSourceInfo *T,
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 136bb5aa4f8..0e6e204e661 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3222,10 +3222,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// while we're still within our own instantiation context.
SmallVector<VTableUse, 16> SavedVTableUses;
std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
- std::deque<PendingImplicitInstantiation>
- SavedPendingLocalImplicitInstantiations;
- SavedPendingLocalImplicitInstantiations.swap(
- PendingLocalImplicitInstantiations);
+ SavePendingLocalImplicitInstantiationsRAII
+ SavedPendingLocalImplicitInstantiations(*this);
if (Recursive) {
VTableUses.swap(SavedVTableUses);
PendingInstantiations.swap(SavedPendingInstantiations);
@@ -3306,8 +3304,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
"PendingInstantiations should be empty before it is discarded.");
PendingInstantiations.swap(SavedPendingInstantiations);
}
- SavedPendingLocalImplicitInstantiations.swap(
- PendingLocalImplicitInstantiations);
}
VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
@@ -3727,6 +3723,8 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
// while we're still within our own instantiation context.
SmallVector<VTableUse, 16> SavedVTableUses;
std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
+ SavePendingLocalImplicitInstantiationsRAII
+ SavedPendingLocalImplicitInstantiations(*this);
if (Recursive) {
VTableUses.swap(SavedVTableUses);
PendingInstantiations.swap(SavedPendingInstantiations);
diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp
index 2b5db0fda3e..bdc5ea0d4a8 100644
--- a/clang/test/SemaTemplate/instantiate-local-class.cpp
+++ b/clang/test/SemaTemplate/instantiate-local-class.cpp
@@ -160,3 +160,23 @@ void call() {
C::func([]() {});
}
}
+
+namespace PR14373 {
+ struct function {
+ template <typename _Functor> function(_Functor __f) { __f(); }
+ };
+ template <typename Func> function exec_func(Func f) {
+ struct functor {
+ functor(Func f) : func(f) {}
+ void operator()() const { func(); }
+ Func func;
+ };
+ return functor(f);
+ }
+ struct Type {
+ void operator()() const {}
+ };
+ int call() {
+ exec_func(Type());
+ }
+}
OpenPOWER on IntegriCloud