19 using namespace clang;
24 bool FromInclude =
false) {
27 if (
auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
28 switch (LSD->getLanguage()) {
31 ExternCLoc = LSD->getBeginLoc();
39 while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
42 if (!isa<TranslationUnitDecl>(DC)) {
44 ? diag::ext_module_import_not_at_top_level_noop
45 : diag::err_module_import_not_at_top_level_fatal)
47 S.
Diag(cast<Decl>(DC)->getBeginLoc(),
48 diag::note_module_import_not_at_top_level)
51 S.
Diag(ImportLoc, diag::ext_module_import_in_extern_c)
53 S.
Diag(ExternCLoc, diag::note_extern_c_begins_here);
59 if (!ModuleScopes.empty() &&
63 assert(getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS &&
64 "unexpectedly encountered multiple global module fragment decls");
65 ModuleScopes.back().BeginLoc = ModuleLoc;
71 auto &Map = PP.getHeaderSearchInfo().getModuleMap();
72 auto *GlobalModule = Map.createGlobalModuleFragmentForModuleUnit(ModuleLoc);
73 assert(GlobalModule &&
"module creation should not fail");
76 ModuleScopes.push_back({});
77 ModuleScopes.back().BeginLoc = ModuleLoc;
78 ModuleScopes.back().Module = GlobalModule;
79 VisibleModules.setVisible(GlobalModule, ModuleLoc);
84 TU->setLocalOwningModule(GlobalModule);
93 assert((getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) &&
94 "should only have module decl in Modules TS or C++20");
99 switch (getLangOpts().getCompilingModule()) {
105 if (MDK != ModuleDeclKind::Implementation)
110 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
112 MDK = ModuleDeclKind::Interface;
116 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
120 Diag(ModuleLoc, diag::err_module_decl_in_header_module);
124 assert(ModuleScopes.size() <= 1 &&
"expected to be at global module scope");
130 if (!ModuleScopes.empty() &&
131 ModuleScopes.back().Module->isModulePurview()) {
132 Diag(ModuleLoc, diag::err_module_redeclaration);
133 Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
134 diag::note_prev_module_declaration);
139 Module *GlobalModuleFragment =
nullptr;
140 if (!ModuleScopes.empty() &&
142 GlobalModuleFragment = ModuleScopes.back().
Module;
146 if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !GlobalModuleFragment) {
147 Diag(ModuleLoc, diag::err_module_decl_not_at_start);
150 ? SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
151 : ModuleScopes.back().BeginLoc;
153 Diag(BeginLoc, diag::note_global_module_introducer_missing)
161 std::string ModuleName;
162 for (
auto &Piece : Path) {
163 if (!ModuleName.empty())
165 ModuleName += Piece.first->getName();
170 if (!getLangOpts().CurrentModule.empty() &&
171 getLangOpts().CurrentModule != ModuleName) {
172 Diag(Path.front().second, diag::err_current_module_name_mismatch)
173 <<
SourceRange(Path.front().second, Path.back().second)
174 << getLangOpts().CurrentModule;
177 const_cast<LangOptions&
>(getLangOpts()).CurrentModule = ModuleName;
179 auto &Map = PP.getHeaderSearchInfo().getModuleMap();
183 case ModuleDeclKind::Interface: {
186 if (
auto *M = Map.findModule(ModuleName)) {
187 Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
188 if (M->DefinitionLoc.isValid())
189 Diag(M->DefinitionLoc, diag::note_prev_module_definition);
190 else if (
const auto *FE = M->getASTFile())
191 Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
198 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
199 GlobalModuleFragment);
200 assert(Mod &&
"module creation should not fail");
204 case ModuleDeclKind::Implementation:
205 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
206 PP.getIdentifierInfo(ModuleName), Path[0].second);
207 Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc},
211 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
213 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
214 GlobalModuleFragment);
219 if (!GlobalModuleFragment) {
220 ModuleScopes.push_back({});
221 if (getLangOpts().ModulesLocalVisibility)
222 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
225 ActOnEndOfTranslationUnitFragment(TUFragmentKind::Global);
229 ModuleScopes.back().BeginLoc = StartLoc;
230 ModuleScopes.back().Module = Mod;
231 ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation;
232 VisibleModules.setVisible(Mod, ModuleLoc);
239 TU->setLocalOwningModule(Mod);
252 : ModuleScopes.back().Module->Kind) {
255 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
259 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
260 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
267 if (!ModuleScopes.back().ModuleInterface) {
268 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
269 Diag(ModuleScopes.back().BeginLoc,
270 diag::note_not_module_interface_add_export)
283 auto &Map = PP.getHeaderSearchInfo().getModuleMap();
284 Module *PrivateModuleFragment =
285 Map.createPrivateModuleFragmentForInterfaceUnit(
286 ModuleScopes.back().Module, PrivateLoc);
287 assert(PrivateModuleFragment &&
"module creation should not fail");
290 ModuleScopes.push_back({});
291 ModuleScopes.back().BeginLoc = ModuleLoc;
292 ModuleScopes.back().Module = PrivateModuleFragment;
293 ModuleScopes.back().ModuleInterface =
true;
294 VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);
301 TU->setLocalOwningModule(PrivateModuleFragment);
312 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
313 if (getLangOpts().ModulesTS) {
314 std::string ModuleName;
315 for (
auto &Piece : Path) {
316 if (!ModuleName.empty())
318 ModuleName += Piece.first->getName();
320 ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second};
330 return ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Mod, Path);
336 if (
auto *ED = dyn_cast<ExportDecl>(DC))
345 VisibleModules.setVisible(Mod, ImportLoc);
357 (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) {
358 Diag(ImportLoc, getLangOpts().isCompilingModule()
359 ? diag::err_module_self_import
360 : diag::err_module_import_in_implementation)
366 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
371 ModCheck = ModCheck->
Parent;
373 IdentifierLocs.push_back(Path[I].second);
379 for (; ModCheck; ModCheck = ModCheck->
Parent) {
385 Mod, IdentifierLocs);
386 CurContext->addDecl(Import);
390 if (!ModuleScopes.empty())
394 if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) {
396 getCurrentModule()->Exports.emplace_back(Mod,
false);
397 }
else if (ExportLoc.
isValid()) {
398 Diag(ExportLoc, diag::err_export_not_in_module_interface);
406 BuildModuleInclude(DirectiveLoc, Mod);
415 bool IsInModuleIncludes =
417 getSourceManager().isWrittenInMainFile(DirectiveLoc);
419 bool ShouldAddImport = !IsInModuleIncludes;
423 if (ShouldAddImport) {
428 if (!ModuleScopes.empty())
431 Consumer.HandleImplicitImportDecl(ImportD);
435 VisibleModules.setVisible(Mod, DirectiveLoc);
441 ModuleScopes.push_back({});
442 ModuleScopes.back().Module = Mod;
443 if (getLangOpts().ModulesLocalVisibility)
444 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
446 VisibleModules.setVisible(Mod, DirectiveLoc);
451 if (getLangOpts().trackLocalOwningModule()) {
452 for (
auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
453 cast<Decl>(DC)->setModuleOwnershipKind(
454 getLangOpts().ModulesLocalVisibility
457 cast<Decl>(DC)->setLocalOwningModule(Mod);
463 if (getLangOpts().ModulesLocalVisibility) {
464 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
467 VisibleNamespaceCache.clear();
470 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
471 "left the wrong module scope");
472 ModuleScopes.pop_back();
476 FileID File = getSourceManager().getFileID(EomLoc);
478 if (EomLoc == getSourceManager().getLocForEndOfFile(File)) {
480 assert(File != getSourceManager().getMainFileID() &&
481 "end of submodule in main source file");
482 DirectiveLoc = getSourceManager().getIncludeLoc(File);
485 DirectiveLoc = EomLoc;
487 BuildModuleInclude(DirectiveLoc, Mod);
490 if (getLangOpts().trackLocalOwningModule()) {
493 for (
auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
494 cast<Decl>(DC)->setLocalOwningModule(getCurrentModule());
495 if (!getCurrentModule())
496 cast<Decl>(DC)->setModuleOwnershipKind(
505 if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery ||
506 VisibleModules.isVisible(Mod))
514 Consumer.HandleImplicitImportDecl(ImportD);
518 VisibleModules.setVisible(Mod, Loc);
534 if (ModuleScopes.empty() || !ModuleScopes.back().Module->isModulePurview()) {
535 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
536 }
else if (!ModuleScopes.back().ModuleInterface) {
537 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
538 Diag(ModuleScopes.back().BeginLoc,
539 diag::note_not_module_interface_add_export)
541 }
else if (ModuleScopes.back().Module->Kind ==
543 Diag(ExportLoc, diag::err_export_in_private_module_fragment);
544 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
548 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
551 if (ND->isAnonymousNamespace()) {
552 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
553 Diag(ND->getLocation(), diag::note_anonymous_namespace);
564 if (!DeferredExportedNamespaces.insert(ND).second)
572 Diag(ExportLoc, diag::err_export_within_export);
574 Diag(ED->getLocation(), diag::note_export);
577 CurContext->addDecl(D);
578 PushDeclContext(S, D);
597 if (isa<EmptyDecl>(D))
598 return UnnamedDeclKind::Empty;
599 if (isa<StaticAssertDecl>(D))
600 return UnnamedDeclKind::StaticAssert;
601 if (isa<FileScopeAsmDecl>(D))
603 if (isa<UsingDirectiveDecl>(D))
604 return UnnamedDeclKind::UsingDirective;
611 case UnnamedDeclKind::Empty:
612 case UnnamedDeclKind::StaticAssert:
615 return InBlock ? diag::ext_export_no_name_block : diag::err_export_no_name;
617 case UnnamedDeclKind::UsingDirective:
619 return diag::ext_export_using_directive;
621 case UnnamedDeclKind::Context:
624 return diag::ext_export_no_names;
627 return diag::err_export_no_name;
629 llvm_unreachable(
"unknown kind");
637 S.
Diag(BlockStart, diag::note_export);
648 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
652 S.
Diag(ND->getLocation(), diag::err_export_internal) << ND;
654 S.
Diag(BlockStart, diag::note_export);
661 if (
auto *USD = dyn_cast<UsingShadowDecl>(D)) {
664 S.
Diag(USD->getLocation(), diag::err_export_using_internal) << Target;
667 S.
Diag(BlockStart, diag::note_export);
673 if (
auto *DC = dyn_cast<DeclContext>(D))
682 bool AllUnnamed =
true;
683 for (
auto *D : DC->
decls())
690 auto *ED = cast<ExportDecl>(D);
692 ED->setRBraceLoc(RBraceLoc);
699 for (
auto *Child : ED->decls()) {
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
DeclResult ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, ModuleIdPath Path)
The parser has processed a module import declaration.
DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, SourceLocation PrivateLoc)
The parser has processed a private-module-fragment declaration that begins the definition of the priv...
This declaration has an owning module, but is only visible to lookups that occur within that module...
static llvm::Optional< UnnamedDeclKind > getUnnamedDeclKind(Decl *D)
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
bool isModuleVisible(const Module *M, bool ModulePrivate=false)
Wrapper for void* pointer.
This is a module that was defined by a module map and built out of header files.
static void checkModuleImportContext(Sema &S, Module *M, SourceLocation ImportLoc, DeclContext *DC, bool FromInclude=false)
Compiling a C++ modules TS module interface unit.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isInvalidDecl() const
This is the private module fragment within some C++ module.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ArrayRef< std::pair< IdentifierInfo *, SourceLocation > > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule, e.g., std.vector.
Compiling a module from a module map.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * Parent
The parent of this module.
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
The parser has processed a module import translated from a #include or similar preprocessing directiv...
Scope - A scope is a transient data structure that is used while parsing the program.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
static bool checkExportedDecl(Sema &S, Decl *D, SourceLocation BlockStart)
Check that it's valid to export D.
static ImportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef< SourceLocation > IdentifierLocs)
Create a new module import declaration.
Sema - This implements semantic analysis and AST building for C.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Compiling a module from a list of header files.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Defines the clang::Preprocessor interface.
Not compiling a module interface at all.
bool isFileContext() const
Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)
Complete the definition of an export declaration.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)
Construct a new module or submodule.
This declaration has an owning module, and is visible when that module is imported.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
Represents a C++ Modules TS module export declaration.
This declaration has an owning module, but is globally visible (typically because its owning module i...
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
static ExportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc)
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
static bool checkExportedDeclContext(Sema &S, DeclContext *DC, SourceLocation BlockStart)
Check that it's valid to export all the declarations in DC.
DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc)
The parser has processed a global-module-fragment declaration that begins the definition of the globa...
This is a fragment of the global module within some C++ module.
Decl * ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, SourceLocation LBraceLoc)
We have parsed the start of an export declaration, including the '{' (if present).
static ImportDecl * CreateImplicit(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc)
Create a new module import declaration for an implicitly-generated import.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, Module *Mod)
Create an implicit import of the given module at the given source location, for error recovery...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod)
The parsed has entered a submodule.
unsigned getUnnamedDeclDiag(UnnamedDeclKind UDK, bool InBlock)
This declaration is not owned by a module.
All of the names in this module are visible.
Assembly: we accept this only so that we can preprocess it.
static const ExportDecl * getEnclosingExportDecl(const Decl *D)
Determine whether D is lexically within an export-declaration.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, bool IsFirstDecl)
The parser has processed a module-declaration that begins the definition of a module interface or imp...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
void addDecl(Decl *D)
Add the declaration D into this context.
static void diagExportedUnnamedDecl(Sema &S, UnnamedDeclKind UDK, Decl *D, SourceLocation BlockStart)
void setRBraceLoc(SourceLocation L)
TranslationUnitDecl * getTranslationUnitDecl() const
void addModuleInitializer(Module *M, Decl *Init)
Add a declaration to the list of declarations that are initialized for a module.
The top declaration context.
void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod)
The parser has left a submodule.
A trivial tuple used to represent a source range.
This represents a decl that may have a name.
TranslationUnitDecl * getTranslationUnitDecl()
SourceLocation getLocation() const
This is a C++ Modules TS module interface unit.
The translation unit is a module.