[clang] [clang-repl] fix top-level statement declaration context (PR #75547)

Pavel Kalugin via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 15 05:42:34 PST 2023


https://github.com/p4vook updated https://github.com/llvm/llvm-project/pull/75547

>From bf1bd0d9618d05ce718a9d834727ff25c3e92a18 Mon Sep 17 00:00:00 2001
From: Pavel Kalugin <pavel at pavelthebest.me>
Date: Fri, 15 Dec 2023 03:07:06 +0300
Subject: [PATCH 1/4] clang-repl: fix top-level statement declaration context

Change the declaration context where we insert top-level
statements to CurrentContext.

Previously, top-level statement declarations were inserted
directly into the translation unit. This is incorrect, as
it leads to ignoring such statements located inside namespaces.

Fixes: #73632
Signed-off-by: Pavel Kalugin <pavel at pavelthebest.me>
---
 clang/include/clang/AST/Decl.h | 3 ++-
 clang/lib/AST/Decl.cpp         | 4 ++--
 clang/lib/Sema/SemaDecl.cpp    | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index cd0878d7082514..7b1d9e8be6c59a 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4440,7 +4440,8 @@ class TopLevelStmtDecl : public Decl {
   virtual void anchor();
 
 public:
-  static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement);
+  static TopLevelStmtDecl *Create(ASTContext &C, DeclContext *DC,
+                                  Stmt *Statement);
   static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
   SourceRange getSourceRange() const override LLVM_READONLY;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 527ea6042daa03..5c0f4f5b6b4ca1 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -5513,13 +5513,13 @@ FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
 
 void TopLevelStmtDecl::anchor() {}
 
-TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) {
+TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, DeclContext *DC,
+                                           Stmt *Statement) {
   assert(Statement);
   assert(C.getLangOpts().IncrementalExtensions &&
          "Must be used only in incremental mode");
 
   SourceLocation BeginLoc = Statement->getBeginLoc();
-  DeclContext *DC = C.getTranslationUnitDecl();
 
   return new (C, DC) TopLevelStmtDecl(DC, BeginLoc, Statement);
 }
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index be6a136ef37bc4..f78fada57f62d3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -20287,8 +20287,8 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
 }
 
 Decl *Sema::ActOnTopLevelStmtDecl(Stmt *Statement) {
-  auto *New = TopLevelStmtDecl::Create(Context, Statement);
-  Context.getTranslationUnitDecl()->addDecl(New);
+  auto *New = TopLevelStmtDecl::Create(Context, CurContext, Statement);
+  CurContext->addDecl(New);
   return New;
 }
 

>From 9a3c0c5e0e3f915ef94bc5612474a98fe4e78b26 Mon Sep 17 00:00:00 2001
From: Pavel Kalugin <pavel at pavelthebest.me>
Date: Fri, 15 Dec 2023 15:05:45 +0300
Subject: [PATCH 2/4] [clang-repl] fix segfault in CleanUpPTU()

Check if the last translation unit or its first declaration
are actually empty and do not nead cleanup.

Previously this caused segmentation fault on empty PTUs.

Fixes: #72980
Signed-off-by: Pavel Kalugin <pavel at pavelthebest.me>
---
 clang/lib/Interpreter/IncrementalParser.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index 370bcbfee8b014..f894af881134bb 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -373,7 +373,15 @@ std::unique_ptr<llvm::Module> IncrementalParser::GenModule() {
 
 void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
   TranslationUnitDecl *MostRecentTU = PTU.TUPart;
+  if (!MostRecentTU) {
+    return;
+  }
+
   TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl();
+  if (!FirstTU) {
+    return;
+  }
+
   if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) {
     for (auto I = Map->begin(); I != Map->end(); ++I) {
       StoredDeclsList &List = I->second;

>From 5daf80f5063174646a724c2ecf55c78164717c29 Mon Sep 17 00:00:00 2001
From: Pavel Kalugin <pavel at pavelthebest.me>
Date: Fri, 15 Dec 2023 15:11:43 +0300
Subject: [PATCH 3/4] [clang-repl] fix cleanup context in CleanUpPTU()

Get the last context returned by collectAllContexts() instead of just
the primary context.

This fixes cleanup in nested namespaces: instead of cleaning up all the
namespace hierarchy it cleans up just the innermost namespace.
---
 clang/lib/Interpreter/IncrementalParser.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index f894af881134bb..366610abecb071 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -382,7 +382,13 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
     return;
   }
 
-  if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) {
+  SmallVector<DeclContext *> contexts;
+  FirstTU->collectAllContexts(contexts);
+  if (contexts.empty()) {
+    return;
+  }
+
+  if (StoredDeclsMap *Map = contexts.back()->getLookupPtr()) {
     for (auto I = Map->begin(); I != Map->end(); ++I) {
       StoredDeclsList &List = I->second;
       DeclContextLookupResult R = List.getLookupResult();

>From fd15ef3d8e655442ceeff49ba4283512a5cd07f6 Mon Sep 17 00:00:00 2001
From: Pavel Kalugin <pavel at pavelthebest.me>
Date: Fri, 15 Dec 2023 16:41:53 +0300
Subject: [PATCH 4/4] Fix lookup context

---
 clang/lib/Interpreter/IncrementalParser.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index 366610abecb071..b13f332041f021 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -388,7 +388,7 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
     return;
   }
 
-  if (StoredDeclsMap *Map = contexts.back()->getLookupPtr()) {
+  if (StoredDeclsMap *Map = contexts.back()->getLookupParent()->getLookupPtr()) {
     for (auto I = Map->begin(); I != Map->end(); ++I) {
       StoredDeclsList &List = I->second;
       DeclContextLookupResult R = List.getLookupResult();



More information about the cfe-commits mailing list