[clang] [clang] Allow delayed function instantiation at TU end if initial instantiation fails (PR #117167)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 21 06:57:01 PST 2024
https://github.com/StefanPaulet updated https://github.com/llvm/llvm-project/pull/117167
>From 54199baf4a6a205e0b85f9f528a90b8170a960fa Mon Sep 17 00:00:00 2001
From: StefanPaulet <tudor.stefan.paulet at gmail.com>
Date: Thu, 21 Nov 2024 15:32:56 +0200
Subject: [PATCH 1/2] [clang] Allow delayed function instantiation at TU end if
initial instantiation fails
---
clang/include/clang/Sema/Sema.h | 11 +++++---
clang/lib/Sema/Sema.cpp | 2 +-
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 14 +++++-----
.../instantiate-function-delayed.cpp | 26 +++++++++++++++++++
4 files changed, 42 insertions(+), 11 deletions(-)
create mode 100644 clang/test/SemaTemplate/instantiate-function-delayed.cpp
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6ea6c67447b6f0..ce27260bc78801 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13523,7 +13523,9 @@ class Sema final : public SemaBase {
S.PendingLocalImplicitInstantiations);
}
- void perform() { S.PerformPendingInstantiations(/*LocalOnly=*/true); }
+ void perform(bool AtEndOfTU = false) {
+ S.PerformPendingInstantiations(/*LocalOnly=*/true, AtEndOfTU);
+ }
~LocalEagerInstantiationScope() {
assert(S.PendingLocalImplicitInstantiations.empty() &&
@@ -13568,10 +13570,10 @@ class Sema final : public SemaBase {
S.SavedVTableUses.back().swap(S.VTableUses);
}
- void perform() {
+ void perform(bool AtEndOfTU = false) {
if (Enabled) {
S.DefineUsedVTables();
- S.PerformPendingInstantiations();
+ S.PerformPendingInstantiations(false, AtEndOfTU);
}
}
@@ -13790,7 +13792,8 @@ class Sema final : public SemaBase {
/// Performs template instantiation for all implicit template
/// instantiations we have seen until this point.
- void PerformPendingInstantiations(bool LocalOnly = false);
+ void PerformPendingInstantiations(bool LocalOnly = false,
+ bool AtEndOfTU = false);
TemplateParameterList *
SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 942e7ece4283e3..c97a253239df2b 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1138,7 +1138,7 @@ void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
{
llvm::TimeTraceScope TimeScope("PerformPendingInstantiations");
- PerformPendingInstantiations();
+ PerformPendingInstantiations(false, true);
}
emitDeferredDiags();
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 10efde7c3fe540..0f9a39062750bc 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5267,9 +5267,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// This class may have local implicit instantiations that need to be
// instantiation within this scope.
- LocalInstantiations.perform();
+ LocalInstantiations.perform(AtEndOfTU);
Scope.Exit();
- GlobalInstantiations.perform();
+ GlobalInstantiations.perform(AtEndOfTU);
}
VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
@@ -5612,9 +5612,9 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
// This variable may have local implicit instantiations that need to be
// instantiated within this scope.
- LocalInstantiations.perform();
+ LocalInstantiations.perform(AtEndOfTU);
Local.Exit();
- GlobalInstantiations.perform();
+ GlobalInstantiations.perform(AtEndOfTU);
}
} else {
assert(Var->isStaticDataMember() && PatternDecl->isStaticDataMember() &&
@@ -6448,7 +6448,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
return D;
}
-void Sema::PerformPendingInstantiations(bool LocalOnly) {
+void Sema::PerformPendingInstantiations(bool LocalOnly, bool AtEndOfTU) {
std::deque<PendingImplicitInstantiation> delayedPCHInstantiations;
while (!PendingLocalImplicitInstantiations.empty() ||
(!LocalOnly && !PendingInstantiations.empty())) {
@@ -6476,9 +6476,11 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) {
});
} else {
InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, Function, true,
- DefinitionRequired, true);
+ DefinitionRequired, AtEndOfTU);
if (Function->isDefined())
Function->setInstantiationIsPending(false);
+ else if (!AtEndOfTU)
+ LateParsedInstantiations.push_back(Inst);
}
// Definition of a PCH-ed template declaration may be available only in the TU.
if (!LocalOnly && LangOpts.PCHInstantiateTemplates &&
diff --git a/clang/test/SemaTemplate/instantiate-function-delayed.cpp b/clang/test/SemaTemplate/instantiate-function-delayed.cpp
new file mode 100644
index 00000000000000..286248b48603b7
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-function-delayed.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template <typename T>
+auto foo(T const& arg) -> T;
+
+template <typename Fp, typename Vis>
+auto dispatch(Fp fp, Vis vis) {
+ return fp(vis);
+}
+
+auto baz(int v) {
+ auto callable = []<typename Arg>(Arg const& arg) -> int {
+ return foo(arg);
+ };
+ return dispatch(callable, v);
+}
+
+template <typename T>
+auto foo(T const& arg) -> T {
+ return arg;
+}
+
+int main() {
+ return baz(5);
+}
\ No newline at end of file
>From 2f1f6bbf0c24e409c7317afb2fd5a4e4ea488de4 Mon Sep 17 00:00:00 2001
From: StefanPaulet <65234821+StefanPaulet at users.noreply.github.com>
Date: Thu, 21 Nov 2024 16:56:53 +0200
Subject: [PATCH 2/2] Apply suggestions from code review
Co-authored-by: Timm Baeder <tbaeder at redhat.com>
---
clang/lib/Sema/Sema.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index c97a253239df2b..78b531a0394562 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1138,7 +1138,7 @@ void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
{
llvm::TimeTraceScope TimeScope("PerformPendingInstantiations");
- PerformPendingInstantiations(false, true);
+ PerformPendingInstantiations(/*LocalOnly=*/false, /*AtEndOfTU=*/true);
}
emitDeferredDiags();
More information about the cfe-commits
mailing list