================
@@ -191,30 +197,149 @@ void IncrementalParser::withdrawMostRecentTU(
   C.TUDecl = Prev;
 }
 
+/// Returns newest declaration of whatever D redeclares that still lives 
outside
+/// DiscardedTU
+static NamedDecl *findSurvivingPrevDecl(NamedDecl *D,
+                                        TranslationUnitDecl *DiscardedTU) {
+  for (Decl *Prev = D->getPreviousDecl(); Prev; Prev = Prev->getPreviousDecl())
+    if (Prev->getTranslationUnitDecl() != DiscardedTU)
+      return dyn_cast<NamedDecl>(Prev);
+  return nullptr;
+}
+
+/// Unlink everything a discarded re-opening of a namespace put into it.
+static void dropContainingMembers(NamespaceDecl *ND) {
+  llvm::SmallVector<Decl *, 8> Members(ND->decls());
+  for (Decl *M : Members)
+    ND->removeDecl(M);
----------------
SahilPatidar wrote:

I think there may be a gap in `withdrawRedeclImpl<NamespaceDecl>` when a 
discarded reopening contains a member that is itself a redeclaration.

For example:
```cpp
PTU1: namespace ns { class Foo; }
PTU2: namespace ns { class Foo { ... }; }
```
```cpp
PTU1: namespace outer { namespace ns { class Foo; } }
PTU2: namespace outer { namespace ns { class Foo { ... }; } }
```
When PTU2 is withdrawn:
```cpp
dropContainingMembers(ND);
unlinkRedeclChain(D, Prev);
```
This seems to correctly repair the ns redeclaration chain, but I think Foo 
itself still needs some recovery:

1. Foo(2)’s RedeclLink does not seem to be repaired, so the chain still point 
to the discarded Foo(2) instead of Foo(1).
2. `removeDecl(Foo(2))` removes Foo(2) from the "Foo" lookup entry, but does 
not restore Foo(1). 

This looks similar to what `DeclContextRepairer::repairLookupEntry` was trying 
to handle. 

We have several cases like this where fixing each part separately will keep 
adding more special cases. This is one of the main reasons I’m working on a 
centralized error-recovery model, separate from `IncrementalParser`, to handle 
these rollback cases in one place across redecl chains, lookup entries, and 
other related AST/Decl state.

For the current issue, I think we should move the redeclaration-related 
recovery logic into a separate component, independent of IncrementalParser.

https://github.com/llvm/llvm-project/pull/218149
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to