[clang] [C++][Modules] Import declaration should in global module fragment, module interface or module implementation (PR #164106)

via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 18 10:55:42 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-modules

Author: None (yronglin)

<details>
<summary>Changes</summary>

This patch implement the restriction for C++ import declaration, it's can only appears in global module fragment, module interface or module implementation

[cpp.pre](https://eel.is/c++draft/cpp.pre):
```
module-file:
    pp-global-module-fragment[opt] pp-module group[opt] pp-private-module-fragment[opt]
```


Since this patch. the following code is ill-formed:

```cpp
// Need to add a 'module;' directive before import directive.
impot std; 
```

---
Full diff: https://github.com/llvm/llvm-project/pull/164106.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+3) 
- (modified) clang/lib/Parse/Parser.cpp (+7) 
- (modified) clang/lib/Sema/SemaModule.cpp (+1-1) 
- (added) clang/test/CXX/module/cpp.pre/p1.cpp (+10) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index e5e071f43fa75..e930d713b07f3 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1814,6 +1814,9 @@ def err_import_in_wrong_fragment : Error<
   "module%select{| partition}0 imports cannot be in the %select{global|private}1 module fragment">;
 
 def err_export_empty : Error<"export declaration cannot be empty">;
+def err_import_decl_not_in_module_fragment : Error<
+  "module import declaration can only appears in "
+  "global module fragment, module interface or module implementation">;
 }
 
 let CategoryName = "Generics Issue" in {
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index ec01faf446e8d..ecddd93d197a4 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -2486,6 +2486,13 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
     SeenError = false;
     break;
   case Sema::ModuleImportState::FirstDecl:
+    if (getLangOpts().CPlusPlusModules) {
+      Diag(ImportLoc, diag::err_import_decl_not_in_module_fragment);
+      Diag(ImportLoc, diag::note_global_module_introducer_missing)
+          << FixItHint::CreateInsertion(PP.getMainFileFirstPPTokenLoc(),
+                                        "module;");
+    }
+
     // If we found an import decl as the first declaration, we must be not in
     // a C++20 module unit or we are in an invalid state.
     ImportState = Sema::ModuleImportState::NotACXX20Module;
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index a2aa3eaaa7f6d..e525f64f9a7e9 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -342,7 +342,7 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
     Diag(ModuleLoc, diag::err_module_decl_not_at_start);
     SourceLocation BeginLoc = PP.getMainFileFirstPPTokenLoc();
     Diag(BeginLoc, diag::note_global_module_introducer_missing)
-        << FixItHint::CreateInsertion(BeginLoc, "module;\n");
+        << FixItHint::CreateInsertion(BeginLoc, "module;");
   }
 
   // C++23 [module.unit]p1: ... The identifiers module and import shall not
diff --git a/clang/test/CXX/module/cpp.pre/p1.cpp b/clang/test/CXX/module/cpp.pre/p1.cpp
new file mode 100644
index 0000000000000..3ec7556734f65
--- /dev/null
+++ b/clang/test/CXX/module/cpp.pre/p1.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 %t/import_is_first_decl.cpp -fsyntax-only -verify
+
+//--- import_is_first_decl.cpp
+import std; // expected-error {{module import declaration can only appears in global module fragment, module interface or module implementation}}
+// expected-note at -1 {{add 'module;' to the start of the file to introduce a global module fragment}}
+// expected-error at -2 {{module 'std' not found}}

``````````

</details>


https://github.com/llvm/llvm-project/pull/164106


More information about the cfe-commits mailing list