[clang] [lldb] [C++20][Modules] Do not update the declaration generation number if the redeclaration chain completion was delayed. (PR #129982)

Michael Park via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 6 22:47:51 PST 2025


================
@@ -9180,6 +9180,12 @@ bool Sema::hasAcceptableDefinition(NamedDecl *D, NamedDecl **Suggested,
   if (!getLangOpts().Modules && !getLangOpts().ModulesLocalVisibility)
     return true;
 
+  // The external source may have additional definitions of this entity that are
+  // visible, so complete the redeclaration chain now.
+  if (auto *Source = Context.getExternalSource()) {
+    Source->CompleteRedeclChain(D);
+  }
----------------
mpark wrote:

Further findings: in this case, what I'm seeing is that [`LazyGenerationalUpdatePtr::get`](https://github.com/llvm/llvm-project/blob/main/clang/include/clang/AST/ExternalASTSource.h#L487-L497) is called twice for [4].

The first invocation, the generation numbers don't match, and `CompleteRedeclChain` is called (*outside* of the deserialization stage) and gets to [`DC->lookup(Name);`](https://github.com/llvm/llvm-project/blob/c6d95c441a29a45782ff72d6cb82839b86fd0e4a/clang/lib/Serialization/ASTReader.cpp#L7862). We don't discover the definition in the first invocation.

The second invocation is from [here](https://github.com/llvm/llvm-project/blob/c6d95c441a29a45782ff72d6cb82839b86fd0e4a/clang/lib/Sema/SemaType.cpp#L9174) (via the `getMostRecentDecl()` call within `getDefinition`). This time, the generation numbers **match**, and `CompleteRedeclChain` is **not** called. However, if I explicitly invoke `CompleteRedeclChain` on it, it gets to the same `DC->lookup(Name);` line as before with exactly the same values for `DC` and `Name`. However, this time the definition **is** found. To be clear, this is invoking `CompleteRedeclChain` on [4] **directly** rather than on [1], [2] or [3], and also not **indirectly** via something like `getMostRecentDecl()` or `redecls()` since `CompleteRedeclChain` will not be called through those functions because the generation numbers match.

In short, I'm seeing that the `DC->lookup(Name)` has different behaviors between two invocations, without either generation numbers changing. I wonder if maybe another module was loaded in between the two calls, and the `ExternalASTSource`'s generation number should have been incremented but it wasn't for some reason...

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


More information about the cfe-commits mailing list