Author: Vassil Vassilev Date: 2024-06-04T13:55:03Z New Revision: d999ce0302f06d250f6d496b56a5a5f2dc331e61
URL: https://github.com/llvm/llvm-project/commit/d999ce0302f06d250f6d496b56a5a5f2dc331e61 DIFF: https://github.com/llvm/llvm-project/commit/d999ce0302f06d250f6d496b56a5a5f2dc331e61.diff LOG: Reland "[clang-repl] Extend the C support. (#89804)" Original commit message:" [clang-repl] Extend the C support. (#89804) The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. " It was reverted in dfdf1c5fe45a82b9c578306f3d7627fd251d63f8 because it broke the bots of lldb. This failure was subtle to debug but the current model does not work well with ObjectiveC support in lldb. This patch does cleans up the partial translation units in ObjectiveC. In future if we want to support ObjectiveC we need to understand what exactly lldb is doing when recovering from errors... Added: clang/test/Interpreter/execute.c Modified: clang/lib/Interpreter/IncrementalParser.cpp clang/lib/Sema/SemaDecl.cpp Removed: ################################################################################ diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..5bc8385d874a1 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr<llvm::Module> IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector<NamedDecl *> NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { + auto *ND = dyn_cast<NamedDecl>(D); + if (!ND) + continue; + // Check if we need to clean up the IdResolver chain. + if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 08483e6ebd67f..7ff05ae514ebe 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2284,9 +2284,13 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) CheckPoppedLabel(LD, *this, addDiag); - // Remove this name from our lexical scope, and warn on it if we haven't - // already. - IdResolver.RemoveDecl(D); + // Partial translation units that are created in incremental processing must + // not clean up the IdResolver because PTUs should take into account the + // declarations that came from previous PTUs. + if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC) + IdResolver.RemoveDecl(D); + + // Warn on it if we are shadowing a declaration. auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast<FieldDecl>(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 0000000000000..44a3a32c93011 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() { \ + printf("i = %d\n", i); \ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.000000, m=0x0] + +%quit _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits