14#ifndef LLVM_CLANG_LEX_MODULEMAP_H
15#define LLVM_CLANG_LEX_MODULEMAP_H
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/PointerIntPair.h"
24#include "llvm/ADT/SmallPtrSet.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringMap.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/StringSet.h"
29#include "llvm/ADT/TinyPtrVector.h"
30#include "llvm/ADT/Twine.h"
39class DiagnosticsEngine;
49 virtual void anchor();
96 Module *SourceModule =
nullptr;
103 llvm::StringMap<Module *> Modules;
107 llvm::DenseMap<const IdentifierInfo *, Module *> CachedModuleLoads;
113 unsigned NumCreatedModules = 0;
117 llvm::StringMap<llvm::StringSet<>> PendingLinkAsModule;
162 llvm::PointerIntPair<Module *, 3, ModuleHeaderRole> Storage;
169 return A.Storage == B.Storage;
172 return A.Storage != B.Storage;
194 explicit operator bool()
const {
195 return Storage.getPointer() !=
nullptr;
205 llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>;
212 mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> LazyHeadersBySize;
215 mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>>
216 LazyHeadersByModTime;
224 llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
231 unsigned CurrentModuleScopeID = 0;
233 llvm::DenseMap<Module *, unsigned> ModuleScopeIDs;
238 unsigned IsSystem : 1;
241 unsigned IsExternC : 1;
244 unsigned IsExhaustive : 1;
248 unsigned NoUndeclaredIncludes : 1;
252 NoUndeclaredIncludes(
false) {}
256 struct InferredDirectory {
258 unsigned InferModules : 1;
265 const FileEntry *ModuleMapFile;
269 SmallVector<std::string, 2> ExcludedModules;
271 InferredDirectory() : InferModules(
false) {}
276 llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
280 llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy;
282 llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps;
286 llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
301 resolveExport(Module *Mod,
const Module::UnresolvedExportDecl &
Unresolved,
302 bool Complain)
const;
315 Module *resolveModuleId(
const ModuleId &
Id, Module *Mod,
bool Complain)
const;
324 void addUnresolvedHeader(Module *Mod,
325 Module::UnresolvedHeaderDirective Header,
326 bool &NeedsFramework);
338 findHeader(Module *M,
const Module::UnresolvedHeaderDirective &Header,
339 SmallVectorImpl<char> &RelativePathName,
bool &NeedsFramework);
347 void resolveHeader(Module *M,
const Module::UnresolvedHeaderDirective &Header,
348 bool &NeedsFramework);
353 bool resolveAsBuiltinHeader(Module *M,
354 const Module::UnresolvedHeaderDirective &Header);
361 HeadersMap::iterator findKnownHeader(
const FileEntry *
File);
369 KnownHeader findHeaderInUmbrellaDirs(
const FileEntry *
File,
370 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
374 KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(
const FileEntry *
File);
378 bool isHeaderInUmbrellaDirs(
const FileEntry *
File) {
379 SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
380 return static_cast<bool>(findHeaderInUmbrellaDirs(
File, IntermediateDirs));
383 Module *inferFrameworkModule(
const DirectoryEntry *FrameworkDir,
384 Attributes Attrs, Module *
Parent);
398 ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
399 const LangOptions &LangOpts,
const TargetInfo *Target,
400 HeaderSearch &HeaderInfo);
406 void setTarget(
const TargetInfo &Target);
411 BuiltinIncludeDir = Dir;
416 return BuiltinIncludeDir;
425 Callbacks.push_back(std::move(Callback));
443 bool AllowTextual =
false,
444 bool AllowExcluded =
false);
470 std::optional<const FileEntry *>
File)
const;
487 bool RequestingModuleIsModuleInterface,
498 const Module *RequestingModule)
const;
606 assert(!ExistingModule->
Parent &&
"expected top-level module");
607 assert(ModuleScopeIDs.count(ExistingModule) &&
"unknown module");
608 return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID;
613 auto It = InferredDirectories.find(Dir);
614 return It != InferredDirectories.end() && It->getSecond().InferModules;
653 auto I = AdditionalModMaps.find(M);
654 if (I == AdditionalModMaps.end())
694 const Twine &NameAsWritten,
695 const Twine &PathRelativeToRootModuleDirectory);
700 const Twine &NameAsWritten,
701 const Twine &PathRelativeToRootModuleDirectory);
740 llvm::iterator_range<module_iterator>
modules()
const {
746 CachedModuleLoads[&II] = M;
751 auto I = CachedModuleLoads.find(&II);
752 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.
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 parser as it reads module map files.
virtual void moduleMapFileRead(SourceLocation FileStart, const FileEntry &File, bool IsSystem)
Called when a module map file has been read.
virtual ~ModuleMapCallbacks()=default
virtual void moduleMapAddUmbrellaHeader(FileManager *FileMgr, const FileEntry *Header)
Called when an umbrella header is added during module map parsing.
virtual void moduleMapAddHeader(StringRef Filename)
Called when a 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 setUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
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.
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Module * findModule(StringRef Name) const
Retrieve a 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)
static bool isBuiltinHeader(StringRef FileName)
Is this a compiler builtin header?
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
void addModuleMapCallbacks(std::unique_ptr< ModuleMapCallbacks > Callback)
Add a module map callback.
bool parseModuleMapFile(const FileEntry *File, bool IsSystem, const DirectoryEntry *HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
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.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap)
const DirectoryEntry * getBuiltinDir() const
Get the directory that contains Clang-supplied include files.
module_iterator module_begin() const
void setBuiltinIncludeDir(const DirectoryEntry *Dir)
Set the directory that contains Clang-supplied include files, such as our stdarg.h or tgmath....
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap)
ArrayRef< KnownHeader > findResolvedModulesForHeader(const FileEntry *File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
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.
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
ArrayRef< KnownHeader > findAllModulesForHeader(const FileEntry *File)
Retrieve all the modules that contain the given header file.
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
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...
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, bool IsExported, Module *Parent=nullptr)
~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.
KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
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.
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
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...
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
bool isHeaderInUnavailableModule(const FileEntry *Header) const
Determine whether the given header is part of a module marked 'unavailable'.
llvm::iterator_range< module_iterator > modules() const
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Describes a module or submodule.
Module * Parent
The parent of this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
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.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.