https://github.com/guitargeek updated https://github.com/llvm/llvm-project/pull/228370
>From 7c2f9b27e5c5e98b0279a93ddc2c611a4e31fa03 Mon Sep 17 00:00:00 2001 From: Jonas Rembser <[email protected]> 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 3cfabb5e5daa18..85282199dc6e8e 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 00000000000000..5e3c9f9444fb81 --- /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 : unsigned { 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
