1313
1414#include " clang/AST/ASTConsumer.h"
1515#include " clang/AST/ASTMutationListener.h"
16+ #include " clang/Basic/SourceLocation.h"
1617#include " clang/Lex/HeaderSearch.h"
18+ #include " clang/Lex/ModuleLoader.h"
1719#include " clang/Lex/Preprocessor.h"
1820#include " clang/Sema/ParsedAttr.h"
1921#include " clang/Sema/SemaInternal.h"
@@ -238,22 +240,21 @@ static bool DiagReservedModuleName(Sema &S, const IdentifierInfo *II,
238240 llvm_unreachable (" fell off a fully covered switch" );
239241}
240242
241- Sema::DeclGroupPtrTy Sema::ActOnModuleDecl (SourceLocation StartLoc,
242- SourceLocation ModuleLoc,
243- ModuleDeclKind MDK,
244- ModuleNameLoc *PathLoc,
245- ModuleNameLoc *PartitionLoc,
246- ModuleImportState &ImportState) {
243+ Sema::DeclGroupPtrTy
244+ Sema::ActOnModuleDecl (SourceLocation StartLoc, SourceLocation ModuleLoc,
245+ ModuleDeclKind MDK, ModuleIdPath Path,
246+ ModuleIdPath Partition, ModuleImportState &ImportState,
247+ bool AtStartOfTU) {
247248 assert (getLangOpts ().CPlusPlusModules &&
248249 " should only have module decl in standard C++ modules" );
249250
250- bool IsFirstDecl = ImportState == ModuleImportState::FirstDecl;
251251 bool SeenGMF = ImportState == ModuleImportState::GlobalFragment;
252252 // If any of the steps here fail, we count that as invalidating C++20
253253 // module state;
254254 ImportState = ModuleImportState::NotACXX20Module;
255255
256- if (PartitionLoc)
256+ bool IsPartition = !Partition.empty ();
257+ if (IsPartition)
257258 switch (MDK) {
258259 case ModuleDeclKind::Implementation:
259260 MDK = ModuleDeclKind::PartitionImplementation;
@@ -282,7 +283,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
282283 // We were asked to compile a module interface unit but this is a module
283284 // implementation unit.
284285 Diag (ModuleLoc, diag::err_module_interface_implementation_mismatch)
285- << FixItHint::CreateInsertion (ModuleLoc, " export " );
286+ << FixItHint::CreateInsertion (ModuleLoc, " export " );
286287 MDK = ModuleDeclKind::Interface;
287288 break ;
288289
@@ -314,7 +315,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
314315
315316 // In C++20, the module-declaration must be the first declaration if there
316317 // is no global module fragment.
317- if (getLangOpts ().CPlusPlusModules && !IsFirstDecl && !SeenGMF) {
318+ if (getLangOpts ().CPlusPlusModules && !AtStartOfTU && !SeenGMF) {
318319 Diag (ModuleLoc, diag::err_module_decl_not_at_start);
319320 SourceLocation BeginLoc =
320321 ModuleScopes.empty ()
@@ -335,39 +336,41 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
335336
336337 // Test the first part of the path to see if it's std[0-9]+ but allow the
337338 // name in a system header.
338- StringRef FirstComponentName =
339- PathLoc->getModuleIdPath ()[0 ].getIdentifierInfo ()->getName ();
340- if (!getSourceManager ().isInSystemHeader (PathLoc->getBeginLoc ()) &&
339+ StringRef FirstComponentName = Path[0 ].getIdentifierInfo ()->getName ();
340+ if (!getSourceManager ().isInSystemHeader (Path[0 ].getLoc ()) &&
341341 (FirstComponentName == " std" ||
342342 (FirstComponentName.starts_with (" std" ) &&
343343 llvm::all_of (FirstComponentName.drop_front (3 ), &llvm::isDigit))))
344- Diag (PathLoc-> getBeginLoc (), diag::warn_reserved_module_name)
345- << PathLoc-> getModuleIdPath () [0 ].getIdentifierInfo ();
344+ Diag (Path[ 0 ]. getLoc (), diag::warn_reserved_module_name)
345+ << Path [0 ].getIdentifierInfo ();
346346
347347 // Then test all of the components in the path to see if any of them are
348348 // using another kind of reserved or invalid identifier.
349- for (auto Part : PathLoc-> getModuleIdPath () ) {
349+ for (auto Part : Path ) {
350350 if (DiagReservedModuleName (*this , Part.getIdentifierInfo (), Part.getLoc ()))
351351 return nullptr ;
352352 }
353353
354354 // Flatten the dots in a module name. Unlike Clang's hierarchical module map
355355 // modules, the dots here are just another character that can appear in a
356356 // module name.
357- std::string ModuleName = PathLoc-> str ( );
358- if (PartitionLoc ) {
357+ std::string ModuleName = ModuleNameLoc::stringFromModuleIdPath (Path );
358+ if (IsPartition ) {
359359 ModuleName += " :" ;
360- ModuleName += PartitionLoc-> str ( );
360+ ModuleName += ModuleNameLoc::stringFromModuleIdPath (Partition );
361361 }
362362 // If a module name was explicitly specified on the command line, it must be
363363 // correct.
364364 if (!getLangOpts ().CurrentModule .empty () &&
365365 getLangOpts ().CurrentModule != ModuleName) {
366- Diag (PathLoc->getBeginLoc (), diag::err_current_module_name_mismatch)
367- << PathLoc->getRange () << getLangOpts ().CurrentModule ;
366+ Diag (Path.front ().getLoc (), diag::err_current_module_name_mismatch)
367+ << SourceRange (Path.front ().getLoc (), IsPartition
368+ ? Partition.back ().getLoc ()
369+ : Path.back ().getLoc ())
370+ << getLangOpts ().CurrentModule ;
368371 return nullptr ;
369372 }
370- const_cast <LangOptions&>(getLangOpts ()).CurrentModule = ModuleName;
373+ const_cast <LangOptions &>(getLangOpts ()).CurrentModule = ModuleName;
371374
372375 auto &Map = PP.getHeaderSearchInfo ().getModuleMap ();
373376 Module *Mod; // The module we are creating.
@@ -378,7 +381,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
378381 // We can't have parsed or imported a definition of this module or parsed a
379382 // module map defining it already.
380383 if (auto *M = Map.findOrLoadModule (ModuleName)) {
381- Diag (PathLoc-> getBeginLoc (), diag::err_module_redefinition) << ModuleName;
384+ Diag (Path[ 0 ]. getLoc (), diag::err_module_redefinition) << ModuleName;
382385 if (M->DefinitionLoc .isValid ())
383386 Diag (M->DefinitionLoc , diag::note_prev_module_definition);
384387 else if (OptionalFileEntryRef FE = M->getASTFile ())
@@ -401,7 +404,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
401404 // keyword nor a module-partition implicitly imports the primary
402405 // module interface unit of the module as if by a module-import-
403406 // declaration.
404- IdentifierLoc ModuleNameLoc (PathLoc-> getBeginLoc (),
407+ IdentifierLoc ModuleNameLoc (Path[ 0 ]. getLoc (),
405408 PP.getIdentifierInfo (ModuleName));
406409
407410 // The module loader will assume we're trying to import the module that
@@ -412,7 +415,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
412415 Interface = getModuleLoader ().loadModule (ModuleLoc, {ModuleNameLoc},
413416 Module::AllVisible,
414417 /* IsInclusionDirective=*/ false );
415- const_cast <LangOptions&>(getLangOpts ()).CurrentModule = ModuleName;
418+ const_cast <LangOptions &>(getLangOpts ()).CurrentModule = ModuleName;
416419
417420 if (!Interface) {
418421 Diag (ModuleLoc, diag::err_module_not_defined) << ModuleName;
@@ -474,7 +477,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
474477
475478 // Make the import decl for the interface in the impl module.
476479 ImportDecl *Import = ImportDecl::Create (Context, CurContext, ModuleLoc,
477- Interface, PathLoc-> getBeginLoc ());
480+ Interface, Path[ 0 ]. getLoc ());
478481 CurContext->addDecl (Import);
479482
480483 // Sequence initialization of the imported module before that of the current
0 commit comments