[clang] [clang-repl] Undo the enumerators of an unscoped enumeration (PR #228370)

Jonas Rembser via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 02:35:13 PDT 2026


https://github.com/guitargeek updated https://github.com/llvm/llvm-project/pull/228370

>From d227eb46be353fc7835d1a7e3f8882a6e873f265 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser at cern.ch>
Date: Thu, 1 Oct 2026 21:06:53 +0000
Subject: [PATCH] [clang-repl] Undo the enumerators of an unscoped enumeration

The enumerators of an unscoped enumeration are in the lookup table of
the enclosing context. Undoing the input that declared the enumeration
removed the enumeration from that context, but its enumerators stayed
visible:

  enum E { Red };
  %undo
  int Red = 5;   // error: redefinition of 'Red' as different kind of symbol

Remove the enumerators of an undone enumeration definition, too.

Assisted-by: Claude Opus 5.5
---
 clang/lib/Interpreter/IncrementalParser.cpp   |  6 +++++
 .../Interpreter/code-undo-enumerators.cpp     | 25 +++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 clang/test/Interpreter/code-undo-enumerators.cpp

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index 3cfabb5e5daa1..85282199dc6e8 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -291,6 +291,12 @@ class ASTDeclUnmerger : public DeclVisitor<ASTDeclUnmerger> {
   void VisitVarDecl(VarDecl *D) { withdraw(D); }
 
   void VisitTagDecl(TagDecl *D) {
+    // The enumerators of an unscoped enumeration are visible in the enclosing
+    // context.
+    if (auto *ED = dyn_cast<EnumDecl>(D);
+        ED && ED->isThisDeclarationADefinition())
+      VisitDeclContext(ED);
+
     NamedDecl *Prev = findSurvivor(D);
     if (!Prev)
       return;
diff --git a/clang/test/Interpreter/code-undo-enumerators.cpp b/clang/test/Interpreter/code-undo-enumerators.cpp
new file mode 100644
index 0000000000000..83cbec17c89af
--- /dev/null
+++ b/clang/test/Interpreter/code-undo-enumerators.cpp
@@ -0,0 +1,25 @@
+// RUN: cat %s | clang-repl | FileCheck %s
+
+// Undoing an unscoped enumeration also undoes its enumerators, which are
+// visible in the enclosing context. Only value printing is checked here:
+// the output of printf() is buffered separately and may come out of order.
+
+enum E { Red, Green };
+%undo
+int Red = 5;
+Red
+// CHECK: (int) 5
+
+enum E2 { Blue };
+%undo
+enum E2 { Blue = 7 };
+Blue
+// CHECK-NEXT: (E2) (Blue) : unsigned int 7
+
+namespace N { enum F { Yellow = 1 }; }
+%undo
+namespace N { int Yellow = 8; }
+N::Yellow
+// CHECK-NEXT: (int) 8
+
+%quit



More information about the cfe-commits mailing list