[clang] [C++20][Modules] Allow import for a header unit after #pragma (PR #111662)

Dmitry Polukhin via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 10 00:56:46 PDT 2024


https://github.com/dmpolukhin updated https://github.com/llvm/llvm-project/pull/111662

>From b92fc2c1b59f655ddd426bdc853621e91c0f70b4 Mon Sep 17 00:00:00 2001
From: Dmitry Polukhin <dmitry.polukhin at gmail.com>
Date: Wed, 9 Oct 2024 04:01:42 -0700
Subject: [PATCH 1/2] [C++20][Modules] Allow import for a header unit after
 #pragma

Summary:
`#pragma` and headers that finish with them shouldn't prevent `import "header_unit.h"` syntax.

Test Plan: check-clang
---
 clang/lib/Lex/Preprocessor.cpp                 | 13 ++++++++++---
 .../import_header_unit_after_pragma.cpp        | 18 ++++++++++++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Headers/import_header_unit_after_pragma.cpp

diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index f0b4593e0cc22e..258154d1e7f45e 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -951,9 +951,16 @@ void Preprocessor::Lex(Token &Result) {
         break;
       [[fallthrough]];
     default:
-      TrackGMFState.handleMisc();
-      StdCXXImportSeqState.handleMisc();
-      ModuleDeclState.handleMisc();
+      if (tok::isPragmaAnnotation(Result.getKind())) {
+        // For `#pragma ...` mimic ';'.
+        TrackGMFState.handleSemi();
+        StdCXXImportSeqState.handleSemi();
+        ModuleDeclState.handleSemi();
+      } else {
+        TrackGMFState.handleMisc();
+        StdCXXImportSeqState.handleMisc();
+        ModuleDeclState.handleMisc();
+      }
       break;
     }
   }
diff --git a/clang/test/Headers/import_header_unit_after_pragma.cpp b/clang/test/Headers/import_header_unit_after_pragma.cpp
new file mode 100644
index 00000000000000..b1ad3b07fea29c
--- /dev/null
+++ b/clang/test/Headers/import_header_unit_after_pragma.cpp
@@ -0,0 +1,18 @@
+// RUN: rm -fR %t
+// RUN: split-file %s %t
+// RUN: cd %t
+// RUN: %clang_cc1 -verify -std=c++20 -emit-header-unit -xc++-user-header bz0.h
+// RUN: %clang_cc1 -verify -std=c++20 -emit-header-unit -xc++-user-header -fmodule-file=bz0.pcm bz.cpp
+
+//--- compare
+#pragma GCC visibility push(default)
+#pragma GCC visibility pop
+
+//--- bz0.h
+#include "compare"
+// expected-no-diagnostics
+
+//--- bz.cpp
+#include "compare"
+
+import "bz0.h"; // expected-warning {{the implementation of header units is in an experimental phase}}

>From 2a9c80ce286d25e543b079c88c53aa1bd99fef9a Mon Sep 17 00:00:00 2001
From: Dmitry Polukhin <dmitry.polukhin at gmail.com>
Date: Thu, 10 Oct 2024 00:54:44 -0700
Subject: [PATCH 2/2] Inline cases for PRAGMA_ANNOTATION

---
 clang/lib/Lex/Preprocessor.cpp | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 258154d1e7f45e..ecc5166d7b814c 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -902,6 +902,10 @@ void Preprocessor::Lex(Token &Result) {
     case tok::r_brace:
       StdCXXImportSeqState.handleCloseBrace();
       break;
+#define PRAGMA_ANNOTATION(X) case tok::annot_##X:
+// For `#pragma ...` mimic ';'.
+#include "clang/Basic/TokenKinds.def"
+#undef PRAGMA_ANNOTATION
     // This token is injected to represent the translation of '#include "a.h"'
     // into "import a.h;". Mimic the notional ';'.
     case tok::annot_module_include:
@@ -951,16 +955,9 @@ void Preprocessor::Lex(Token &Result) {
         break;
       [[fallthrough]];
     default:
-      if (tok::isPragmaAnnotation(Result.getKind())) {
-        // For `#pragma ...` mimic ';'.
-        TrackGMFState.handleSemi();
-        StdCXXImportSeqState.handleSemi();
-        ModuleDeclState.handleSemi();
-      } else {
-        TrackGMFState.handleMisc();
-        StdCXXImportSeqState.handleMisc();
-        ModuleDeclState.handleMisc();
-      }
+      TrackGMFState.handleMisc();
+      StdCXXImportSeqState.handleMisc();
+      ModuleDeclState.handleMisc();
       break;
     }
   }



More information about the cfe-commits mailing list