[clang] [C++20] [Modules] Instantiate pending instantiations when GMF ends (PR #126842)

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 12 19:04:44 PST 2025


================
@@ -1104,9 +1104,13 @@ void Sema::ActOnStartOfTranslationUnit() {
 }
 
 void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
-  // No explicit actions are required at the end of the global module fragment.
-  if (Kind == TUFragmentKind::Global)
+  if (Kind == TUFragmentKind::Global) {
+    // Perform Pending Instantiations at the end of global module fragment so
+    // that the module ownership of TU-level decls won't get messed.
+    llvm::TimeTraceScope TimeScope("PerformPendingInstantiations");
+    PerformPendingInstantiations();
----------------
ChuanqiXu9 wrote:

I feel it is less concerning to me.

> If a template has been instantiated, we don't need to instantiate it again.

It is already the case. When we want to instantiate a template instantiation, we will lookup if we've already instantiated it. And when we lookup if we instantiated an instantiation, we will lookup it in the external source. See `findSpecializationImpl` in DeclTemplate.cpp for details.

> The instantiations should either have no ownership, perhaps homed to the owner of the pattern, or maybe be multiply owned.

On the other hand, if we don't find an instantiation in the external source, we will instantiate it. Then the **same**(?) instantiation may be instantiated to different modules. e.g.,

```
export module a;
export template <class T>
class Templ { ... };

export module b;
import a;
Templ<int> ...; // instantiation attached to module b

export module c;
import a;
Templ<int> ...; // instantiation attached to module c

export module d;
import b;
import c;
Templ<int> ...
```

in the above example, the instantiation of `Templ<int>` may be attached to module b and c in different TUs. And in module d, the instantiation of `Templ<int>` from different modules will be redecls to each other. And these redeclarations may have different modules ownership. So it is already multiply owned.

https://github.com/llvm/llvm-project/pull/126842


More information about the cfe-commits mailing list