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.pau...@gmail.com> Date: Thu, 21 Nov 2024 15:32:56 +0200 Subject: [PATCH 1/3] [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+stefanpau...@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:56:53 +0200 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Timm Baeder <tbae...@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(); >From 8ed13b61cebb90ef3336ffca50eb9013c9710c2e Mon Sep 17 00:00:00 2001 From: StefanPaulet <tudor.stefan.pau...@gmail.com> Date: Fri, 22 Nov 2024 11:51:22 +0200 Subject: [PATCH 3/3] Resolved issue that produced CI fail --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0f9a39062750bc..85443c9adddb9d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5763,9 +5763,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); } void @@ -6529,7 +6529,7 @@ void Sema::PerformPendingInstantiations(bool LocalOnly, bool AtEndOfTU) { // Instantiate static data member definitions or variable template // specializations. InstantiateVariableDefinition(/*FIXME:*/ Inst.second, Var, true, - DefinitionRequired, true); + DefinitionRequired, AtEndOfTU); } if (!LocalOnly && LangOpts.PCHInstantiateTemplates) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits