Skip to content

Commit 4d62929

Browse files
committed
[C++20] [Modules] Disambuguous Clang module and C++20 Named module further
This patch tries to make the boundary of clang module and C++20 named module more clear. The changes included: - Rename `TranslationUnitKind::TU_Module` to `TranslationUnitKind::TU_ClangModule`. - Rename `Sema::ActOnModuleInclude` to `Sema::ActOnAnnotModuleInclude`. - Rename `ActOnModuleBegin` to `Sema::ActOnAnnotModuleBegin`. - Rename `Sema::ActOnModuleEnd` to `Sema::ActOnAnnotModuleEnd`. - Removes a warning if we're trying to compile a non-module unit as C++20 module unit. This is not actually useful and makes (the future) implementation unnecessarily complex. This patch meant to be a NFC fix. But it shows that it fixed a bug suprisingly that previously we would surppress the unused-value warning in named modules. Because it shares the same logic with clang modules, which has headers semantics. This shows the change is meaningful.
1 parent 0d98582 commit 4d62929

File tree

10 files changed

+58
-89
lines changed

10 files changed

+58
-89
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11516,8 +11516,6 @@ def err_module_not_defined : Error<
1151611516
def err_module_redeclaration : Error<
1151711517
"translation unit contains multiple module declarations">;
1151811518
def note_prev_module_declaration : Note<"previous module declaration is here">;
11519-
def err_module_declaration_missing : Error<
11520-
"missing 'export module' declaration in module interface unit">;
1152111519
def err_module_declaration_missing_after_global_module_introducer : Error<
1152211520
"missing 'module' declaration at end of global module fragment "
1152311521
"introduced here">;

clang/include/clang/Basic/LangOptions.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -560,11 +560,6 @@ class LangOptions : public LangOptionsBase {
560560
return getCompilingModule() != CMK_None;
561561
}
562562

563-
/// Are we compiling a standard c++ module interface?
564-
bool isCompilingModuleInterface() const {
565-
return getCompilingModule() == CMK_ModuleInterface;
566-
}
567-
568563
/// Are we compiling a module implementation?
569564
bool isCompilingModuleImplementation() const {
570565
return !isCompilingModule() && !ModuleName.empty();
@@ -993,8 +988,8 @@ enum TranslationUnitKind {
993988
/// not complete.
994989
TU_Prefix,
995990

996-
/// The translation unit is a module.
997-
TU_Module,
991+
/// The translation unit is a clang module.
992+
TU_ClangModule,
998993

999994
/// The translation unit is a is a complete translation unit that we might
1000995
/// incrementally extend later.

clang/include/clang/Frontend/FrontendActions.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class GenerateModuleAction : public ASTFrontendAction {
125125
StringRef InFile) override;
126126

127127
TranslationUnitKind getTranslationUnitKind() override {
128-
return TU_Module;
128+
return TU_ClangModule;
129129
}
130130

131131
bool hasASTFileSupport() const override { return false; }
@@ -138,7 +138,9 @@ class GenerateInterfaceStubsAction : public ASTFrontendAction {
138138
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
139139
StringRef InFile) override;
140140

141-
TranslationUnitKind getTranslationUnitKind() override { return TU_Module; }
141+
TranslationUnitKind getTranslationUnitKind() override {
142+
return TU_ClangModule;
143+
}
142144
bool hasASTFileSupport() const override { return false; }
143145
};
144146

@@ -159,6 +161,8 @@ class GenerateModuleInterfaceAction : public GenerateModuleAction {
159161
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
160162
StringRef InFile) override;
161163

164+
TranslationUnitKind getTranslationUnitKind() override { return TU_Complete; }
165+
162166
std::unique_ptr<raw_pwrite_stream>
163167
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
164168
};

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8064,13 +8064,13 @@ class Sema final {
80648064

80658065
/// The parser has processed a module import translated from a
80668066
/// #include or similar preprocessing directive.
8067-
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
8067+
void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
80688068
void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
80698069

80708070
/// The parsed has entered a submodule.
8071-
void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
8071+
void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
80728072
/// The parser has left a submodule.
8073-
void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod);
8073+
void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod);
80748074

80758075
/// Create an implicit import of the given module at the given
80768076
/// source location, for error recovery, if possible.

clang/lib/Parse/Parser.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
685685
// FIXME: We need a better way to disambiguate C++ clang modules and
686686
// standard C++ modules.
687687
if (!getLangOpts().CPlusPlusModules || !Mod->isHeaderUnit())
688-
Actions.ActOnModuleInclude(Loc, Mod);
688+
Actions.ActOnAnnotModuleInclude(Loc, Mod);
689689
else {
690690
DeclResult Import =
691691
Actions.ActOnModuleImport(Loc, SourceLocation(), Loc, Mod);
@@ -697,15 +697,17 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
697697
}
698698

699699
case tok::annot_module_begin:
700-
Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>(
701-
Tok.getAnnotationValue()));
700+
Actions.ActOnAnnotModuleBegin(
701+
Tok.getLocation(),
702+
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
702703
ConsumeAnnotationToken();
703704
ImportState = Sema::ModuleImportState::NotACXX20Module;
704705
return false;
705706

706707
case tok::annot_module_end:
707-
Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>(
708-
Tok.getAnnotationValue()));
708+
Actions.ActOnAnnotModuleEnd(
709+
Tok.getLocation(),
710+
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
709711
ConsumeAnnotationToken();
710712
ImportState = Sema::ModuleImportState::NotACXX20Module;
711713
return false;
@@ -2708,9 +2710,9 @@ bool Parser::parseMisplacedModuleImport() {
27082710
// happens.
27092711
if (MisplacedModuleBeginCount) {
27102712
--MisplacedModuleBeginCount;
2711-
Actions.ActOnModuleEnd(Tok.getLocation(),
2712-
reinterpret_cast<Module *>(
2713-
Tok.getAnnotationValue()));
2713+
Actions.ActOnAnnotModuleEnd(
2714+
Tok.getLocation(),
2715+
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
27142716
ConsumeAnnotationToken();
27152717
continue;
27162718
}
@@ -2720,18 +2722,18 @@ bool Parser::parseMisplacedModuleImport() {
27202722
return true;
27212723
case tok::annot_module_begin:
27222724
// Recover by entering the module (Sema will diagnose).
2723-
Actions.ActOnModuleBegin(Tok.getLocation(),
2724-
reinterpret_cast<Module *>(
2725-
Tok.getAnnotationValue()));
2725+
Actions.ActOnAnnotModuleBegin(
2726+
Tok.getLocation(),
2727+
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
27262728
ConsumeAnnotationToken();
27272729
++MisplacedModuleBeginCount;
27282730
continue;
27292731
case tok::annot_module_include:
27302732
// Module import found where it should not be, for instance, inside a
27312733
// namespace. Recover by importing the module.
2732-
Actions.ActOnModuleInclude(Tok.getLocation(),
2733-
reinterpret_cast<Module *>(
2734-
Tok.getAnnotationValue()));
2734+
Actions.ActOnAnnotModuleInclude(
2735+
Tok.getLocation(),
2736+
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
27352737
ConsumeAnnotationToken();
27362738
// If there is another module import, process it.
27372739
continue;

clang/lib/Sema/Sema.cpp

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,26 +1207,35 @@ void Sema::ActOnEndOfTranslationUnit() {
12071207
}
12081208

12091209
// A global-module-fragment is only permitted within a module unit.
1210-
bool DiagnosedMissingModuleDeclaration = false;
12111210
if (!ModuleScopes.empty() && ModuleScopes.back().Module->Kind ==
12121211
Module::ExplicitGlobalModuleFragment) {
12131212
Diag(ModuleScopes.back().BeginLoc,
12141213
diag::err_module_declaration_missing_after_global_module_introducer);
1215-
DiagnosedMissingModuleDeclaration = true;
1216-
}
1217-
1218-
if (TUKind == TU_Module) {
1219-
// If we are building a module interface unit, we need to have seen the
1220-
// module declaration by now.
1221-
if (getLangOpts().getCompilingModule() ==
1222-
LangOptions::CMK_ModuleInterface &&
1223-
!isCurrentModulePurview() && !DiagnosedMissingModuleDeclaration) {
1224-
// FIXME: Make a better guess as to where to put the module declaration.
1225-
Diag(getSourceManager().getLocForStartOfFile(
1226-
getSourceManager().getMainFileID()),
1227-
diag::err_module_declaration_missing);
1228-
}
1214+
}
1215+
1216+
// Now we can decide whether the modules we're building need an initializer.
1217+
if (Module *CurrentModule = getCurrentModule();
1218+
CurrentModule && CurrentModule->isInterfaceOrPartition()) {
1219+
auto DoesModNeedInit = [this](Module *M) {
1220+
if (!getASTContext().getModuleInitializers(M).empty())
1221+
return true;
1222+
for (auto [Exported, _] : M->Exports)
1223+
if (Exported->isNamedModuleInterfaceHasInit())
1224+
return true;
1225+
for (Module *I : M->Imports)
1226+
if (I->isNamedModuleInterfaceHasInit())
1227+
return true;
1228+
1229+
return false;
1230+
};
12291231

1232+
CurrentModule->NamedModuleHasInit =
1233+
DoesModNeedInit(CurrentModule) ||
1234+
llvm::any_of(CurrentModule->submodules(),
1235+
[&](auto *SubM) { return DoesModNeedInit(SubM); });
1236+
}
1237+
1238+
if (TUKind == TU_ClangModule) {
12301239
// If we are building a module, resolve all of the exported declarations
12311240
// now.
12321241
if (Module *CurrentModule = PP.getCurrentModule()) {
@@ -1251,28 +1260,6 @@ void Sema::ActOnEndOfTranslationUnit() {
12511260
}
12521261
}
12531262

1254-
// Now we can decide whether the modules we're building need an initializer.
1255-
if (Module *CurrentModule = getCurrentModule();
1256-
CurrentModule && CurrentModule->isInterfaceOrPartition()) {
1257-
auto DoesModNeedInit = [this](Module *M) {
1258-
if (!getASTContext().getModuleInitializers(M).empty())
1259-
return true;
1260-
for (auto [Exported, _] : M->Exports)
1261-
if (Exported->isNamedModuleInterfaceHasInit())
1262-
return true;
1263-
for (Module *I : M->Imports)
1264-
if (I->isNamedModuleInterfaceHasInit())
1265-
return true;
1266-
1267-
return false;
1268-
};
1269-
1270-
CurrentModule->NamedModuleHasInit =
1271-
DoesModNeedInit(CurrentModule) ||
1272-
llvm::any_of(CurrentModule->submodules(),
1273-
[&](auto *SubM) { return DoesModNeedInit(SubM); });
1274-
}
1275-
12761263
// Warnings emitted in ActOnEndOfTranslationUnit() should be emitted for
12771264
// modules when they are built, not every time they are used.
12781265
emitAndClearUnusedLocalTypedefWarnings();
@@ -1358,7 +1345,7 @@ void Sema::ActOnEndOfTranslationUnit() {
13581345
// noise. Don't warn for a use from a module: either we should warn on all
13591346
// file-scope declarations in modules or not at all, but whether the
13601347
// declaration is used is immaterial.
1361-
if (!Diags.hasErrorOccurred() && TUKind != TU_Module) {
1348+
if (!Diags.hasErrorOccurred() && TUKind != TU_ClangModule) {
13621349
// Output warning for unused file scoped decls.
13631350
for (UnusedFileScopedDeclsType::iterator
13641351
I = UnusedFileScopedDecls.begin(ExternalSource.get()),

clang/lib/Sema/SemaModule.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
713713
return Import;
714714
}
715715

716-
void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
716+
void Sema::ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
717717
checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
718718
BuildModuleInclude(DirectiveLoc, Mod);
719719
}
@@ -723,9 +723,9 @@ void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
723723
// in that buffer do not qualify as module imports; they're just an
724724
// implementation detail of us building the module.
725725
//
726-
// FIXME: Should we even get ActOnModuleInclude calls for those?
726+
// FIXME: Should we even get ActOnAnnotModuleInclude calls for those?
727727
bool IsInModuleIncludes =
728-
TUKind == TU_Module &&
728+
TUKind == TU_ClangModule &&
729729
getSourceManager().isWrittenInMainFile(DirectiveLoc);
730730

731731
// If we are really importing a module (not just checking layering) due to an
@@ -752,7 +752,7 @@ void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
752752
}
753753
}
754754

755-
void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
755+
void Sema::ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
756756
checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
757757

758758
ModuleScopes.push_back({});
@@ -776,7 +776,7 @@ void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
776776
}
777777
}
778778

779-
void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
779+
void Sema::ActOnAnnotModuleEnd(SourceLocation EomLoc, Module *Mod) {
780780
if (getLangOpts().ModulesLocalVisibility) {
781781
VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
782782
// Leaving a module hides namespace names, so our visible namespace cache

clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ module A; // #module-decl
1515
// expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}}
1616
#define INTERFACE
1717
#endif
18-
#else
19-
#ifdef BUILT_AS_INTERFACE
20-
// expected-error@1 {{missing 'export module' declaration in module interface unit}}
21-
#endif
2218
#endif
2319

2420
#ifndef INTERFACE

clang/test/Modules/missing-module-declaration.cppm

Lines changed: 0 additions & 13 deletions
This file was deleted.

clang/test/Modules/pr72828.cppm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct s {
1717

1818
void f() {
1919
auto [x] = s();
20-
[x] {};
20+
(void) [x] {};
2121
}
2222

2323
// Check that we can generate the LLVM IR expectedly.

0 commit comments

Comments
 (0)