summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp8
-rw-r--r--clang/test/SemaTemplate/instantiate-local-class.cpp13
2 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8f2e95a6152..57faa1cbad8 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1302,11 +1302,19 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// DR1484 clarifies that the members of a local class are instantiated as part
// of the instantiation of their enclosing entity.
if (D->isCompleteDefinition() && D->isLocalClass()) {
+ Sema::SavePendingLocalImplicitInstantiationsRAII
+ SavedPendingLocalImplicitInstantiations(SemaRef);
+
SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
TSK_ImplicitInstantiation,
/*Complain=*/true);
+
SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
TSK_ImplicitInstantiation);
+
+ // This class may have local implicit instantiations that need to be
+ // performed within this scope.
+ SemaRef.PerformPendingInstantiations(/*LocalOnly=*/true);
}
SemaRef.DiagnoseUnusedNestedTypedefs(Record);
diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp
index 367134a2a53..668fb6fa65b 100644
--- a/clang/test/SemaTemplate/instantiate-local-class.cpp
+++ b/clang/test/SemaTemplate/instantiate-local-class.cpp
@@ -213,3 +213,16 @@ namespace PR23194 {
return make_seed_pair();
}
}
+
+namespace PR20625 {
+template <typename T>
+void f() {
+ struct N {
+ static constexpr int get() { return 42; }
+ };
+ constexpr int n = N::get();
+ static_assert(n == 42, "n == 42");
+}
+
+void g() { f<void>(); }
+}
OpenPOWER on IntegriCloud