14#ifndef LLVM_CLANG_LEX_MODULEMAP_H
15#define LLVM_CLANG_LEX_MODULEMAP_H
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/DenseSet.h"
25#include "llvm/ADT/PointerIntPair.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringMap.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/ADT/StringSet.h"
30#include "llvm/ADT/TinyPtrVector.h"
31#include "llvm/ADT/Twine.h"
50 virtual void anchor();
90 Module *SourceModule =
nullptr;
93 llvm::SpecificBumpPtrAllocator<Module> ModulesAlloc;
100 llvm::StringMap<Module *> Modules;
104 llvm::DenseMap<const IdentifierInfo *, Module *> CachedModuleLoads;
107 unsigned NumCreatedModules = 0;
111 llvm::StringMap<llvm::StringSet<>> PendingLinkAsModule;
156 llvm::PointerIntPair<Module *, 3, ModuleHeaderRole> Storage;
163 return A.Storage == B.Storage;
166 return A.Storage != B.Storage;
188 explicit operator bool()
const {
189 return Storage.getPointer() !=
nullptr;
198 using HeadersMap = llvm::DenseMap<FileEntryRef, SmallVector<KnownHeader, 1>>;
205 mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> LazyHeadersBySize;
208 mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>>
209 LazyHeadersByModTime;
217 llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
225 llvm::DenseMap<std::pair<const FileEntry *, const Module *>,
SourceLocation>
229 llvm::DenseSet<const FileEntry *> DiagnosedDuplicateHeaders;
236 unsigned CurrentModuleScopeID = 0;
238 llvm::DenseMap<Module *, unsigned> ModuleScopeIDs;
243 struct InferredDirectory {
245 LLVM_PREFERRED_TYPE(
bool)
246 unsigned InferModules : 1;
259 InferredDirectory() : InferModules(
false) {}
264 llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
268 llvm::DenseMap<const Module *, FileID> InferredModuleAllowedBy;
270 llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps;
274 llvm::DenseMap<const FileEntry *, bool> LoadedModuleMap;
275 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>
280 llvm::DenseMap<const FileEntry *, FileID> ModuleMapLocalFileID;
282 std::vector<std::unique_ptr<modulemap::ModuleMapFile>> ParsedModuleMaps;
287 llvm::StringMap<
SmallVector<std::pair<
const modulemap::ModuleMapFile *,
288 const modulemap::ModuleDecl *>,
305 resolveExport(Module *Mod,
const Module::UnresolvedExportDecl &
Unresolved,
306 bool Complain)
const;
319 Module *resolveModuleId(
const ModuleId &Id, Module *Mod,
bool Complain)
const;
328 void addUnresolvedHeader(Module *Mod,
329 Module::UnresolvedHeaderDirective Header,
330 bool &NeedsFramework);
342 findHeader(Module *M,
const Module::UnresolvedHeaderDirective &Header,
343 SmallVectorImpl<char> &RelativePathName,
bool &NeedsFramework);
351 void resolveHeader(Module *M,
const Module::UnresolvedHeaderDirective &Header,
352 bool &NeedsFramework);
357 bool resolveAsBuiltinHeader(Module *M,
358 const Module::UnresolvedHeaderDirective &Header);
365 HeadersMap::iterator findKnownHeader(FileEntryRef
File);
368 void diagnoseDuplicateHeaderOwnership(SourceLocation FilenameLoc,
369 StringRef Filename, FileEntryRef
File,
370 HeadersMap::iterator
Known);
378 KnownHeader findHeaderInUmbrellaDirs(
379 FileEntryRef
File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs);
383 KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef
File);
387 bool isHeaderInUmbrellaDirs(FileEntryRef
File) {
389 return static_cast<bool>(findHeaderInUmbrellaDirs(
File, IntermediateDirs));
392 Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, Attributes Attrs,
407 ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
408 const LangOptions &LangOpts,
const TargetInfo *Target,
409 HeaderSearch &HeaderInfo);
432 Callbacks.push_back(std::move(
Callback));
450 bool AllowExcluded =
false);
487 std::optional<const FileEntry *>
File)
const;
504 bool RequestingModuleIsModuleInterface,
515 const Module *RequestingModule)
const;
528 return Modules.contains(Name) || ParsedModules.contains(Name);
581 bool IsFramework,
bool IsExplicit) {
598 Module *Parent =
nullptr);
649 assert(!ExistingModule->
Parent &&
"expected top-level module");
650 assert(ModuleScopeIDs.count(ExistingModule) &&
"unknown module");
651 return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID;
656 auto It = InferredDirectories.find(Dir);
657 return It != InferredDirectories.end() && It->getSecond().InferModules;
698 auto I = AdditionalModMaps.find(M);
699 if (I == AdditionalModMaps.end())
739 const Twine &NameAsWritten,
740 const Twine &PathRelativeToRootModuleDirectory,
753 const Twine &NameAsWritten,
754 const Twine &PathRelativeToRootModuleDirectory,
795 bool ImplicitlyDiscovered,
797 unsigned *Offset =
nullptr,
803 auto It = ParsedModuleMap.find(
File);
804 if (It == ParsedModuleMap.end())
816 llvm::iterator_range<module_iterator>
modules()
const {
822 CachedModuleLoads[&II] = M;
827 auto I = CachedModuleLoads.find(&II);
828 if (I == CachedModuleLoads.end())
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Concrete class used by the front-end to report problems and issues.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A mechanism to observe the actions of the module map loader as it reads module map files.
virtual void moduleMapFileRead(SourceLocation FileStart, FileEntryRef File, bool IsSystem)
Called when a module map file has been read.
virtual ~ModuleMapCallbacks()=default
virtual void moduleMapAddHeader(StringRef Filename)
Called when a header is added during module map parsing.
virtual void moduleMapAddUmbrellaHeader(FileEntryRef Header)
Called when an umbrella header is added during module map parsing.
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
friend class ModuleMapLoader
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, DirectoryEntryRef Dir, FileID ID=FileID(), SourceLocation ExternModuleLoc=SourceLocation())
Parse a module map without creating clang::Module instances.
void dump()
Dump the contents of the module map, for debugging purposes.
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
llvm::StringMap< Module * >::const_iterator module_iterator
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
ModuleRef lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Module * findModule(StringRef Name) const
Retrieve an already loaded module with the given name.
void finishModuleDeclarationScope()
Creates a new declaration scope for module names, allowing previously defined modules to shadow defin...
bool canInferFrameworkModule(const DirectoryEntry *Dir) const
Check whether a framework module can be inferred in the given directory.
bool mayShadowNewModule(Module *ExistingModule)
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
bool isModuleKnown(StringRef Name) const
Determine if a top-level module named Name was loaded or parsed.
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory, SourceLocation Loc=SourceLocation())
Sets the umbrella header of the given module to the given header.
void addModuleMapCallbacks(std::unique_ptr< ModuleMapCallbacks > Callback)
Add a module map callback.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false, SourceLocation Loc=SourceLocation())
Adds this header to the given module.
void setBuiltinIncludeDir(DirectoryEntryRef Dir)
Set the directory that contains Clang-supplied include files, such as our stdarg.h or tgmath....
void recordDirectoryDependencies(Module *Mod, StringRef Dir)
Record that Mod depends on the listing of Dir. Dir is a VFS path.
OptionalFileEntryRef getModuleMapFileForName(StringRef Name) const
Find the module map that defines the top-level module Name, without loading it.
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
module_iterator module_begin() const
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Load the given module map file, and record any modules we encounter.
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
std::optional< Module * > getCachedModuleLoad(const IdentifierInfo &II)
Return a cached module load.
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
OptionalFileEntryRef findUmbrellaHeaderForModule(Module *M, std::string NameAsWritten, SmallVectorImpl< char > &RelativePathName)
Find the FileEntry for an umbrella header in a module as if it was written in the module map as a hea...
FileID getModuleMapFileIDForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory, SourceLocation Loc=SourceLocation())
Sets the umbrella directory of the given module to the given directory.
llvm::DenseSet< FileEntryRef > AdditionalModMapsSet
Module * findOrCreateModuleFirst(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Call ModuleMap::findOrCreateModule and throw away the information whether the module was found or cre...
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Module * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Create new submodule, assuming it does not exist.
static void canonicalizeDirectoryDependency(const FileManager &FileMgr, SmallVectorImpl< char > &Path)
Spell Path the way directory dependencies are recorded: absolute, with dots removed.
module_iterator module_end() const
AdditionalModMapsSet * getAdditionalModuleMapFiles(const Module *M)
Get any module map files other than getModuleMapFileForUniquing(M) that define submodules of a top-le...
const modulemap::ModuleMapFile * getParsedModuleMap(FileEntryRef File) const
Get the ModuleMapFile for a FileEntry previously parsed with parseModuleMapFile.
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
OptionalDirectoryEntryRef getBuiltinDir() const
Get the directory that contains Clang-supplied include files.
~ModuleMap()
Destroy the module map.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
void setTarget(const TargetInfo &Target)
Set the target information.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
void cacheModuleLoad(const IdentifierInfo &II, Module *M)
Cache a module load. M might be nullptr.
ModuleHeaderRole
Flags describing the role of a module header.
@ PrivateHeader
This header is included but private.
@ ExcludedHeader
This header is explicitly excluded from the module.
@ NormalHeader
This header is normally included in the module.
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module interface unit.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
void loadAllParsedModules()
Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)
Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...
Module * findOrLoadModule(StringRef Name)
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
llvm::iterator_range< module_iterator > modules() const
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Reference to a module that consists of either an existing/materialized Module object,...
Describes a module or submodule.
std::pair< ModuleRef, bool > ExportDecl
Describes an exported module.
Module * Parent
The parent of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Exposes information about the current target.
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
The set of attributes that can be attached to a module.
Represents the parsed form of a module map file.