25 bool FromInclude =
false) {
28 if (
auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
29 switch (LSD->getLanguage()) {
32 ExternCLoc = LSD->getBeginLoc();
40 while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
43 if (!isa<TranslationUnitDecl>(DC)) {
45 ? diag::ext_module_import_not_at_top_level_noop
46 : diag::err_module_import_not_at_top_level_fatal)
48 S.
Diag(cast<Decl>(DC)->getBeginLoc(),
49 diag::note_module_import_not_at_top_level)
52 S.
Diag(ImportLoc, diag::ext_module_import_in_extern_c)
54 S.
Diag(ExternCLoc, diag::note_extern_c_begins_here);
67 for (
auto &Piece : Path) {
70 Name += Piece.first->getName();
79 PushGlobalModuleFragment(ModuleLoc);
91 TU->setLocalOwningModule(GlobalModule);
97void Sema::HandleStartOfHeaderUnit() {
99 "Header units are only valid for C++20 modules");
104 if (HUName.empty()) {
118 assert(F &&
"failed to find the header unit source?");
121 Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H);
122 assert(Mod &&
"module creation should not fail");
123 ModuleScopes.push_back({});
124 ModuleScopes.back().BeginLoc = StartOfTU;
125 ModuleScopes.back().Module = Mod;
126 ModuleScopes.back().ModuleInterface =
true;
133 TU->setLocalOwningModule(Mod);
147 if (II->
isStr(
"module") || II->
isStr(
"import"))
159 if (Reason != Valid) {
160 S.
Diag(Loc, diag::err_invalid_module_name) << II << (
int)Reason;
171 "should only have module decl in standard C++ modules");
179 bool IsPartition = !Partition.empty();
189 llvm_unreachable(
"how did we get a partition type set?");
208 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
214 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
218 Diag(ModuleLoc, diag::err_module_decl_in_header_unit);
222 assert(ModuleScopes.size() <= 1 &&
"expected to be at global module scope");
228 if (isCurrentModulePurview()) {
229 Diag(ModuleLoc, diag::err_module_redeclaration);
231 diag::note_prev_module_declaration);
236 SeenGMF == (
bool)this->TheGlobalModuleFragment) &&
237 "mismatched global module state");
241 if (
getLangOpts().CPlusPlusModules && !IsFirstDecl && !SeenGMF) {
242 Diag(ModuleLoc, diag::err_module_decl_not_at_start);
246 : ModuleScopes.back().BeginLoc;
248 Diag(BeginLoc, diag::note_global_module_introducer_missing)
262 StringRef FirstComponentName = Path[0].first->getName();
264 (FirstComponentName ==
"std" ||
265 (FirstComponentName.startswith(
"std") &&
266 llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit)))) {
267 Diag(Path[0].second, diag::err_invalid_module_name)
268 << Path[0].first << 1;
274 for (
auto Part : Path) {
291 Diag(Path.front().second, diag::err_current_module_name_mismatch)
293 ? Partition.back().second
294 : Path.back().second)
308 if (
auto *M = Map.findModule(ModuleName)) {
309 Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
310 if (M->DefinitionLoc.isValid())
311 Diag(M->DefinitionLoc, diag::note_prev_module_definition);
313 Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
320 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
323 assert(Mod &&
"module creation should not fail");
332 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
346 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
348 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
350 Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName);
357 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
362 if (!this->TheGlobalModuleFragment) {
363 ModuleScopes.push_back({});
365 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
372 ModuleScopes.back().BeginLoc = StartLoc;
373 ModuleScopes.back().Module = Mod;
384 TU->setLocalOwningModule(Mod);
425 : ModuleScopes.back().Module->Kind) {
432 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
436 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
437 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
441 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
442 Diag(ModuleScopes.back().BeginLoc,
443 diag::note_not_module_interface_add_export)
459 Module *PrivateModuleFragment =
460 Map.createPrivateModuleFragmentForInterfaceUnit(
461 ModuleScopes.back().Module, PrivateLoc);
462 assert(PrivateModuleFragment &&
"module creation should not fail");
465 ModuleScopes.push_back({});
466 ModuleScopes.back().BeginLoc = ModuleLoc;
467 ModuleScopes.back().Module = PrivateModuleFragment;
468 ModuleScopes.back().ModuleInterface =
true;
469 VisibleModules.
setVisible(PrivateModuleFragment, ModuleLoc);
476 TU->setLocalOwningModule(PrivateModuleFragment);
486 assert((!IsPartition ||
getLangOpts().CPlusPlusModules) &&
487 "partition seen in non-C++20 code?");
491 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
493 std::string ModuleName;
496 assert(!ModuleScopes.empty() &&
"in a module purview, but no module?");
497 Module *NamedMod = ModuleScopes.back().Module;
518 if (
getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
520 Diag(ImportLoc, diag::err_module_self_import_cxx20)
521 << ModuleName << !ModuleScopes.back().ModuleInterface;
536 if (
auto *ED = dyn_cast<ExportDecl>(DC))
555 ? diag::err_module_self_import
556 : diag::err_module_import_in_implementation)
566 for (
Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->
Parent)
570 IdentifierLocs.push_back(Path[0].second);
573 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
578 ModCheck = ModCheck->
Parent;
580 IdentifierLocs.push_back(Path[I].second);
585 Mod, IdentifierLocs);
590 if (!ModuleScopes.empty())
596 Diag(ExportLoc, diag::err_export_partition_impl)
598 }
else if (!ModuleScopes.empty() &&
599 (ModuleScopes.back().ModuleInterface ||
601 ModuleScopes.back().Module->isGlobalModule()))) {
609 }
else if (ExportLoc.
isValid()) {
613 Diag(ExportLoc, diag::err_export_not_in_module_interface);
630 bool IsInModuleIncludes =
634 bool ShouldAddImport = !IsInModuleIncludes;
638 if (ShouldAddImport) {
643 if (!ModuleScopes.empty())
654 getLangOpts().CurrentModule, DirectiveLoc,
false,
false);
656 assert(ThisModule &&
"was expecting a module if building one");
663 ModuleScopes.push_back({});
664 ModuleScopes.back().Module = Mod;
666 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
675 cast<Decl>(DC)->setModuleOwnershipKind(
679 cast<Decl>(DC)->setLocalOwningModule(Mod);
686 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
692 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
693 "left the wrong module scope");
694 ModuleScopes.pop_back();
703 "end of submodule in main source file");
707 DirectiveLoc = EomLoc;
718 cast<Decl>(DC)->setModuleOwnershipKind(
759 if (!isCurrentModulePurview()) {
760 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
763 }
else if (!ModuleScopes.back().ModuleInterface) {
764 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
765 Diag(ModuleScopes.back().BeginLoc,
766 diag::note_not_module_interface_add_export)
770 }
else if (ModuleScopes.back().Module->Kind ==
772 Diag(ExportLoc, diag::err_export_in_private_module_fragment);
773 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
779 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
782 if (ND->isAnonymousNamespace()) {
783 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
784 Diag(ND->getLocation(), diag::note_anonymous_namespace);
795 if (!DeferredExportedNamespaces.insert(ND).second)
803 Diag(ExportLoc, diag::err_export_within_export);
805 Diag(ED->getLocation(), diag::note_export);
818enum class UnnamedDeclKind {
829 if (isa<EmptyDecl>(D))
830 return UnnamedDeclKind::Empty;
831 if (isa<StaticAssertDecl>(D))
832 return UnnamedDeclKind::StaticAssert;
833 if (isa<FileScopeAsmDecl>(D))
834 return UnnamedDeclKind::Asm;
835 if (isa<UsingDirectiveDecl>(D))
836 return UnnamedDeclKind::UsingDirective;
843 case UnnamedDeclKind::Empty:
844 case UnnamedDeclKind::StaticAssert:
847 return InBlock ? diag::ext_export_no_name_block : diag::err_export_no_name;
849 case UnnamedDeclKind::UsingDirective:
851 return diag::ext_export_using_directive;
853 case UnnamedDeclKind::Namespace:
855 return diag::introduces_no_names;
857 case UnnamedDeclKind::Context:
860 return diag::ext_export_no_names;
862 case UnnamedDeclKind::Asm:
863 return diag::err_export_no_name;
865 llvm_unreachable(
"unknown kind");
873 S.
Diag(BlockStart, diag::note_export);
884 bool HasName =
false;
885 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
888 HasName = (
bool)ND->getDeclName();
890 S.
Diag(ND->getLocation(), diag::err_export_internal) << ND;
892 S.
Diag(BlockStart, diag::note_export);
899 if (
auto *USD = dyn_cast<UsingShadowDecl>(D)) {
903 S.
Diag(USD->getLocation(), diag::err_export_using_internal)
905 S.
Diag(
Target->getLocation(), diag::note_using_decl_target);
907 S.
Diag(BlockStart, diag::note_export);
913 if (
auto *DC = dyn_cast<DeclContext>(D)) {
914 if (isa<NamespaceDecl>(D) && DC->decls().empty()) {
920 }
else if (DC->getRedeclContext()->isFileContext() && !isa<EnumDecl>(D))
929 bool AllUnnamed =
true;
930 for (
auto *D : DC->
decls())
937 auto *ED = cast<ExportDecl>(D);
939 ED->setRBraceLoc(RBraceLoc);
946 for (
auto *Child : ED->decls()) {
953 if (
auto *FD = dyn_cast<FunctionDecl>(Child)) {
961 if (FD->isInlineSpecified() && !FD->isDefined())
962 PendingInlineFuncDecls.insert(FD);
973 if (!TheGlobalModuleFragment) {
979 assert(TheGlobalModuleFragment &&
"module creation should not fail");
982 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,
985 VisibleModules.
setVisible(TheGlobalModuleFragment, BeginLoc);
987 return TheGlobalModuleFragment;
990void Sema::PopGlobalModuleFragment() {
991 assert(!ModuleScopes.empty() &&
993 "left the wrong module scope, which is not global module fragment");
994 ModuleScopes.pop_back();
999 Module **M = IsExported ? &TheExportedImplicitGlobalModuleFragment
1000 : &TheImplicitGlobalModuleFragment;
1006 assert(*M &&
"module creation should not fail");
1009 ModuleScopes.push_back({BeginLoc, *M,
1016void Sema::PopImplicitGlobalModuleFragment() {
1017 assert(!ModuleScopes.empty() &&
1019 "left the wrong module scope, which is not global module fragment");
1020 ModuleScopes.pop_back();
1030 if (!CurrentModuleUnit)
Defines the clang::Preprocessor interface.
static std::optional< UnnamedDeclKind > getUnnamedDeclKind(Decl *D)
static bool DiagReservedModuleName(Sema &S, const IdentifierInfo *II, SourceLocation Loc)
Tests whether the given identifier is reserved as a module name and diagnoses if it is.
static const ExportDecl * getEnclosingExportDecl(const Decl *D)
Determine whether D is lexically within an export-declaration.
static bool checkExportedDecl(Sema &S, Decl *D, SourceLocation BlockStart)
Check that it's valid to export D.
static std::string stringFromPath(ModuleIdPath Path)
static void checkModuleImportContext(Sema &S, Module *M, SourceLocation ImportLoc, DeclContext *DC, bool FromInclude=false)
unsigned getUnnamedDeclDiag(UnnamedDeclKind UDK, bool InBlock)
static void diagExportedUnnamedDecl(Sema &S, UnnamedDeclKind UDK, Decl *D, SourceLocation BlockStart)
static bool checkExportedDeclContext(Sema &S, DeclContext *DC, SourceLocation BlockStart)
Check that it's valid to export all the declarations in DC.
virtual void HandleImplicitImportDecl(ImportDecl *D)
Handle an ImportDecl that was implicitly created due to an inclusion directive.
TranslationUnitDecl * getTranslationUnitDecl() const
void addModuleInitializer(Module *M, Decl *Init)
Add a declaration to the list of declarations that are initialized for a module.
void setNamedModuleForCodeGen(Module *M)
Set the (C++20) module we are building.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
void addDecl(Decl *D)
Add the declaration D into this context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
SourceLocation getLocation() const
@ VisibleWhenImported
This declaration has an owning module, and is visible when that module is imported.
@ Unowned
This declaration is not owned by a module.
@ ReachableWhenImported
This declaration has an owning module, and is visible to lookups that occurs within that module.
@ ModulePrivate
This declaration has an owning module, but is only visible to lookups that occur within that module.
@ Visible
This declaration has an owning module, but is globally visible (typically because its owning module i...
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
Represents a standard C++ module export declaration.
static ExportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc)
void setRBraceLoc(SourceLocation L)
StringRef getName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
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.
One of these records is kept for each identifier that is lexed.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
static ImportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef< SourceLocation > IdentifierLocs)
Create a new module import declaration.
static ImportDecl * CreateImplicit(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc)
Create a new module import declaration for an implicitly-generated import.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
@ CMK_HeaderUnit
Compiling a module header unit.
@ CMK_ModuleMap
Compiling a module from a module map.
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
@ CMK_None
Not compiling a module interface at all.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
virtual void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc)=0
Make the given module visible.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, bool IsExported, Module *Parent=nullptr)
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
Describes a module or submodule.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
@ AllVisible
All of the names in this module are visible.
Module * Parent
The parent of this module.
ModuleKind Kind
The kind of this module.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
StringRef getPrimaryModuleInterfaceName() const
Get the primary module interface name from a partition.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
@ ModulePartitionInterface
This is a C++ 20 module partition interface.
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
@ ModuleHeaderUnit
This is a C++ 20 header unit.
@ ModulePartitionImplementation
This is a C++ 20 module partition implementation.
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
This represents a decl that may have a name.
Wrapper for void* pointer.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
HeaderSearch & getHeaderSearchInfo() const
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod)
The parsed has entered a submodule.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
@ PartitionImplementation
'module X:Y;'
@ Interface
'export module X;'
@ Implementation
'module X;'
@ PartitionInterface
'export module X:Y;'
llvm::DenseMap< NamedDecl *, NamedDecl * > VisibleNamespaceCache
Map from the most recent declaration of a namespace to the most recent visible declaration of that na...
DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, ModuleIdPath Partition, ModuleImportState &ImportState)
The parser has processed a module-declaration that begins the definition of a module interface or imp...
DeclResult ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, ModuleIdPath Path, bool IsPartition=false)
The parser has processed a module import declaration.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ASTContext & getASTContext() const
Decl * ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, SourceLocation LBraceLoc)
We have parsed the start of an export declaration, including the '{' (if present).
const LangOptions & getLangOpts() const
bool isModuleUnitOfCurrentTU(const Module *M) const
void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind)
DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc)
The parser has processed a global-module-fragment declaration that begins the definition of the globa...
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
Module * getCurrentModule() const
Get the module unit whose scope we are currently within.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, SourceLocation PrivateLoc)
The parser has processed a private-module-fragment declaration that begins the definition of the priv...
SourceManager & getSourceManager() const
void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
bool isModuleVisible(const Module *M, bool ModulePrivate=false)
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
The parser has processed a module import translated from a #include or similar preprocessing directiv...
@ Global
The global module fragment, between 'module;' and a module-declaration.
@ Normal
A normal translation unit fragment.
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
@ FirstDecl
Parsing the first decl in a TU.
@ GlobalFragment
after 'module;' but before 'module X;'
@ NotACXX20Module
Not a C++20 TU, or an invalid state was found.
@ ImportAllowed
after 'module X;' but before any non-import decl.
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with the preprocessor.
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
SourceManager & SourceMgr
void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod)
The parser has left a submodule.
Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)
Complete the definition of an export declaration.
void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, Module *Mod)
Create an implicit import of the given module at the given source location, for error recovery,...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
A trivial tuple used to represent a source range.
The top declaration context.
SourceLocation getImportLoc(const Module *M) const
Get the location at which the import of a module was triggered.
bool isVisible(const Module *M) const
Determine whether a module is visible.
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef) {})
Make a specific module visible.
ArrayRef< std::pair< IdentifierInfo *, SourceLocation > > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ InternalLinkage
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ ModuleLinkage
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Asm
Assembly: we accept this only so that we can preprocess it.
@ TU_Module
The translation unit is a module.