Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- ModuleMap.h - Describe the layout of modules -------------*- C++ -*-===// |
| 2 | // |
||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
| 6 | // |
||
| 7 | //===----------------------------------------------------------------------===// |
||
| 8 | // |
||
| 9 | // This file defines the ModuleMap interface, which describes the layout of a |
||
| 10 | // module as it relates to headers. |
||
| 11 | // |
||
| 12 | //===----------------------------------------------------------------------===// |
||
| 13 | |||
| 14 | #ifndef LLVM_CLANG_LEX_MODULEMAP_H |
||
| 15 | #define LLVM_CLANG_LEX_MODULEMAP_H |
||
| 16 | |||
| 17 | #include "clang/Basic/IdentifierTable.h" |
||
| 18 | #include "clang/Basic/LangOptions.h" |
||
| 19 | #include "clang/Basic/Module.h" |
||
| 20 | #include "clang/Basic/SourceLocation.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" |
||
| 31 | #include <ctime> |
||
| 32 | #include <memory> |
||
| 33 | #include <optional> |
||
| 34 | #include <string> |
||
| 35 | #include <utility> |
||
| 36 | |||
| 37 | namespace clang { |
||
| 38 | |||
| 39 | class DiagnosticsEngine; |
||
| 40 | class DirectoryEntry; |
||
| 41 | class FileEntry; |
||
| 42 | class FileManager; |
||
| 43 | class HeaderSearch; |
||
| 44 | class SourceManager; |
||
| 45 | |||
| 46 | /// A mechanism to observe the actions of the module map parser as it |
||
| 47 | /// reads module map files. |
||
| 48 | class ModuleMapCallbacks { |
||
| 49 | virtual void anchor(); |
||
| 50 | |||
| 51 | public: |
||
| 52 | virtual ~ModuleMapCallbacks() = default; |
||
| 53 | |||
| 54 | /// Called when a module map file has been read. |
||
| 55 | /// |
||
| 56 | /// \param FileStart A SourceLocation referring to the start of the file's |
||
| 57 | /// contents. |
||
| 58 | /// \param File The file itself. |
||
| 59 | /// \param IsSystem Whether this is a module map from a system include path. |
||
| 60 | virtual void moduleMapFileRead(SourceLocation FileStart, |
||
| 61 | const FileEntry &File, bool IsSystem) {} |
||
| 62 | |||
| 63 | /// Called when a header is added during module map parsing. |
||
| 64 | /// |
||
| 65 | /// \param Filename The header file itself. |
||
| 66 | virtual void moduleMapAddHeader(StringRef Filename) {} |
||
| 67 | |||
| 68 | /// Called when an umbrella header is added during module map parsing. |
||
| 69 | /// |
||
| 70 | /// \param FileMgr FileManager instance |
||
| 71 | /// \param Header The umbrella header to collect. |
||
| 72 | virtual void moduleMapAddUmbrellaHeader(FileManager *FileMgr, |
||
| 73 | const FileEntry *Header) {} |
||
| 74 | }; |
||
| 75 | |||
| 76 | class ModuleMap { |
||
| 77 | SourceManager &SourceMgr; |
||
| 78 | DiagnosticsEngine &Diags; |
||
| 79 | const LangOptions &LangOpts; |
||
| 80 | const TargetInfo *Target; |
||
| 81 | HeaderSearch &HeaderInfo; |
||
| 82 | |||
| 83 | llvm::SmallVector<std::unique_ptr<ModuleMapCallbacks>, 1> Callbacks; |
||
| 84 | |||
| 85 | /// The directory used for Clang-supplied, builtin include headers, |
||
| 86 | /// such as "stdint.h". |
||
| 87 | const DirectoryEntry *BuiltinIncludeDir = nullptr; |
||
| 88 | |||
| 89 | /// Language options used to parse the module map itself. |
||
| 90 | /// |
||
| 91 | /// These are always simple C language options. |
||
| 92 | LangOptions MMapLangOpts; |
||
| 93 | |||
| 94 | /// The module that the main source file is associated with (the module |
||
| 95 | /// named LangOpts::CurrentModule, if we've loaded it). |
||
| 96 | Module *SourceModule = nullptr; |
||
| 97 | |||
| 98 | /// Submodules of the current module that have not yet been attached to it. |
||
| 99 | /// (Ownership is transferred if/when we create an enclosing module.) |
||
| 100 | llvm::SmallVector<std::unique_ptr<Module>, 8> PendingSubmodules; |
||
| 101 | |||
| 102 | /// The top-level modules that are known. |
||
| 103 | llvm::StringMap<Module *> Modules; |
||
| 104 | |||
| 105 | /// Module loading cache that includes submodules, indexed by IdentifierInfo. |
||
| 106 | /// nullptr is stored for modules that are known to fail to load. |
||
| 107 | llvm::DenseMap<const IdentifierInfo *, Module *> CachedModuleLoads; |
||
| 108 | |||
| 109 | /// Shadow modules created while building this module map. |
||
| 110 | llvm::SmallVector<Module*, 2> ShadowModules; |
||
| 111 | |||
| 112 | /// The number of modules we have created in total. |
||
| 113 | unsigned NumCreatedModules = 0; |
||
| 114 | |||
| 115 | /// In case a module has a export_as entry, it might have a pending link |
||
| 116 | /// name to be determined if that module is imported. |
||
| 117 | llvm::StringMap<llvm::StringSet<>> PendingLinkAsModule; |
||
| 118 | |||
| 119 | public: |
||
| 120 | /// Use PendingLinkAsModule information to mark top level link names that |
||
| 121 | /// are going to be replaced by export_as aliases. |
||
| 122 | void resolveLinkAsDependencies(Module *Mod); |
||
| 123 | |||
| 124 | /// Make module to use export_as as the link dependency name if enough |
||
| 125 | /// information is available or add it to a pending list otherwise. |
||
| 126 | void addLinkAsDependency(Module *Mod); |
||
| 127 | |||
| 128 | /// Flags describing the role of a module header. |
||
| 129 | enum ModuleHeaderRole { |
||
| 130 | /// This header is normally included in the module. |
||
| 131 | NormalHeader = 0x0, |
||
| 132 | |||
| 133 | /// This header is included but private. |
||
| 134 | PrivateHeader = 0x1, |
||
| 135 | |||
| 136 | /// This header is part of the module (for layering purposes) but |
||
| 137 | /// should be textually included. |
||
| 138 | TextualHeader = 0x2, |
||
| 139 | |||
| 140 | /// This header is explicitly excluded from the module. |
||
| 141 | ExcludedHeader = 0x4, |
||
| 142 | |||
| 143 | // Caution: Adding an enumerator needs other changes. |
||
| 144 | // Adjust the number of bits for KnownHeader::Storage. |
||
| 145 | // Adjust the HeaderFileInfoTrait::ReadData streaming. |
||
| 146 | // Adjust the HeaderFileInfoTrait::EmitData streaming. |
||
| 147 | // Adjust ModuleMap::addHeader. |
||
| 148 | }; |
||
| 149 | |||
| 150 | /// Convert a header kind to a role. Requires Kind to not be HK_Excluded. |
||
| 151 | static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind); |
||
| 152 | |||
| 153 | /// Convert a header role to a kind. |
||
| 154 | static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role); |
||
| 155 | |||
| 156 | /// Check if the header with the given role is a modular one. |
||
| 157 | static bool isModular(ModuleHeaderRole Role); |
||
| 158 | |||
| 159 | /// A header that is known to reside within a given module, |
||
| 160 | /// whether it was included or excluded. |
||
| 161 | class KnownHeader { |
||
| 162 | llvm::PointerIntPair<Module *, 3, ModuleHeaderRole> Storage; |
||
| 163 | |||
| 164 | public: |
||
| 165 | KnownHeader() : Storage(nullptr, NormalHeader) {} |
||
| 166 | KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) {} |
||
| 167 | |||
| 168 | friend bool operator==(const KnownHeader &A, const KnownHeader &B) { |
||
| 169 | return A.Storage == B.Storage; |
||
| 170 | } |
||
| 171 | friend bool operator!=(const KnownHeader &A, const KnownHeader &B) { |
||
| 172 | return A.Storage != B.Storage; |
||
| 173 | } |
||
| 174 | |||
| 175 | /// Retrieve the module the header is stored in. |
||
| 176 | Module *getModule() const { return Storage.getPointer(); } |
||
| 177 | |||
| 178 | /// The role of this header within the module. |
||
| 179 | ModuleHeaderRole getRole() const { return Storage.getInt(); } |
||
| 180 | |||
| 181 | /// Whether this header is available in the module. |
||
| 182 | bool isAvailable() const { |
||
| 183 | return getRole() != ExcludedHeader && getModule()->isAvailable(); |
||
| 184 | } |
||
| 185 | |||
| 186 | /// Whether this header is accessible from the specified module. |
||
| 187 | bool isAccessibleFrom(Module *M) const { |
||
| 188 | return !(getRole() & PrivateHeader) || |
||
| 189 | (M && M->getTopLevelModule() == getModule()->getTopLevelModule()); |
||
| 190 | } |
||
| 191 | |||
| 192 | // Whether this known header is valid (i.e., it has an |
||
| 193 | // associated module). |
||
| 194 | explicit operator bool() const { |
||
| 195 | return Storage.getPointer() != nullptr; |
||
| 196 | } |
||
| 197 | }; |
||
| 198 | |||
| 199 | using AdditionalModMapsSet = llvm::SmallPtrSet<const FileEntry *, 1>; |
||
| 200 | |||
| 201 | private: |
||
| 202 | friend class ModuleMapParser; |
||
| 203 | |||
| 204 | using HeadersMap = |
||
| 205 | llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>; |
||
| 206 | |||
| 207 | /// Mapping from each header to the module that owns the contents of |
||
| 208 | /// that header. |
||
| 209 | HeadersMap Headers; |
||
| 210 | |||
| 211 | /// Map from file sizes to modules with lazy header directives of that size. |
||
| 212 | mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> LazyHeadersBySize; |
||
| 213 | |||
| 214 | /// Map from mtimes to modules with lazy header directives with those mtimes. |
||
| 215 | mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>> |
||
| 216 | LazyHeadersByModTime; |
||
| 217 | |||
| 218 | /// Mapping from directories with umbrella headers to the module |
||
| 219 | /// that is generated from the umbrella header. |
||
| 220 | /// |
||
| 221 | /// This mapping is used to map headers that haven't explicitly been named |
||
| 222 | /// in the module map over to the module that includes them via its umbrella |
||
| 223 | /// header. |
||
| 224 | llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs; |
||
| 225 | |||
| 226 | /// A generation counter that is used to test whether modules of the |
||
| 227 | /// same name may shadow or are illegal redefinitions. |
||
| 228 | /// |
||
| 229 | /// Modules from earlier scopes may shadow modules from later ones. |
||
| 230 | /// Modules from the same scope may not have the same name. |
||
| 231 | unsigned CurrentModuleScopeID = 0; |
||
| 232 | |||
| 233 | llvm::DenseMap<Module *, unsigned> ModuleScopeIDs; |
||
| 234 | |||
| 235 | /// The set of attributes that can be attached to a module. |
||
| 236 | struct Attributes { |
||
| 237 | /// Whether this is a system module. |
||
| 238 | unsigned IsSystem : 1; |
||
| 239 | |||
| 240 | /// Whether this is an extern "C" module. |
||
| 241 | unsigned IsExternC : 1; |
||
| 242 | |||
| 243 | /// Whether this is an exhaustive set of configuration macros. |
||
| 244 | unsigned IsExhaustive : 1; |
||
| 245 | |||
| 246 | /// Whether files in this module can only include non-modular headers |
||
| 247 | /// and headers from used modules. |
||
| 248 | unsigned NoUndeclaredIncludes : 1; |
||
| 249 | |||
| 250 | Attributes() |
||
| 251 | : IsSystem(false), IsExternC(false), IsExhaustive(false), |
||
| 252 | NoUndeclaredIncludes(false) {} |
||
| 253 | }; |
||
| 254 | |||
| 255 | /// A directory for which framework modules can be inferred. |
||
| 256 | struct InferredDirectory { |
||
| 257 | /// Whether to infer modules from this directory. |
||
| 258 | unsigned InferModules : 1; |
||
| 259 | |||
| 260 | /// The attributes to use for inferred modules. |
||
| 261 | Attributes Attrs; |
||
| 262 | |||
| 263 | /// If \c InferModules is non-zero, the module map file that allowed |
||
| 264 | /// inferred modules. Otherwise, nullptr. |
||
| 265 | const FileEntry *ModuleMapFile; |
||
| 266 | |||
| 267 | /// The names of modules that cannot be inferred within this |
||
| 268 | /// directory. |
||
| 269 | SmallVector<std::string, 2> ExcludedModules; |
||
| 270 | |||
| 271 | InferredDirectory() : InferModules(false) {} |
||
| 272 | }; |
||
| 273 | |||
| 274 | /// A mapping from directories to information about inferring |
||
| 275 | /// framework modules from within those directories. |
||
| 276 | llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories; |
||
| 277 | |||
| 278 | /// A mapping from an inferred module to the module map that allowed the |
||
| 279 | /// inference. |
||
| 280 | llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy; |
||
| 281 | |||
| 282 | llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps; |
||
| 283 | |||
| 284 | /// Describes whether we haved parsed a particular file as a module |
||
| 285 | /// map. |
||
| 286 | llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap; |
||
| 287 | |||
| 288 | /// Resolve the given export declaration into an actual export |
||
| 289 | /// declaration. |
||
| 290 | /// |
||
| 291 | /// \param Mod The module in which we're resolving the export declaration. |
||
| 292 | /// |
||
| 293 | /// \param Unresolved The export declaration to resolve. |
||
| 294 | /// |
||
| 295 | /// \param Complain Whether this routine should complain about unresolvable |
||
| 296 | /// exports. |
||
| 297 | /// |
||
| 298 | /// \returns The resolved export declaration, which will have a NULL pointer |
||
| 299 | /// if the export could not be resolved. |
||
| 300 | Module::ExportDecl |
||
| 301 | resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved, |
||
| 302 | bool Complain) const; |
||
| 303 | |||
| 304 | /// Resolve the given module id to an actual module. |
||
| 305 | /// |
||
| 306 | /// \param Id The module-id to resolve. |
||
| 307 | /// |
||
| 308 | /// \param Mod The module in which we're resolving the module-id. |
||
| 309 | /// |
||
| 310 | /// \param Complain Whether this routine should complain about unresolvable |
||
| 311 | /// module-ids. |
||
| 312 | /// |
||
| 313 | /// \returns The resolved module, or null if the module-id could not be |
||
| 314 | /// resolved. |
||
| 315 | Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const; |
||
| 316 | |||
| 317 | /// Add an unresolved header to a module. |
||
| 318 | /// |
||
| 319 | /// \param Mod The module in which we're adding the unresolved header |
||
| 320 | /// directive. |
||
| 321 | /// \param Header The unresolved header directive. |
||
| 322 | /// \param NeedsFramework If Mod is not a framework but a missing header would |
||
| 323 | /// be found in case Mod was, set it to true. False otherwise. |
||
| 324 | void addUnresolvedHeader(Module *Mod, |
||
| 325 | Module::UnresolvedHeaderDirective Header, |
||
| 326 | bool &NeedsFramework); |
||
| 327 | |||
| 328 | /// Look up the given header directive to find an actual header file. |
||
| 329 | /// |
||
| 330 | /// \param M The module in which we're resolving the header directive. |
||
| 331 | /// \param Header The header directive to resolve. |
||
| 332 | /// \param RelativePathName Filled in with the relative path name from the |
||
| 333 | /// module to the resolved header. |
||
| 334 | /// \param NeedsFramework If M is not a framework but a missing header would |
||
| 335 | /// be found in case M was, set it to true. False otherwise. |
||
| 336 | /// \return The resolved file, if any. |
||
| 337 | OptionalFileEntryRef |
||
| 338 | findHeader(Module *M, const Module::UnresolvedHeaderDirective &Header, |
||
| 339 | SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework); |
||
| 340 | |||
| 341 | /// Resolve the given header directive. |
||
| 342 | /// |
||
| 343 | /// \param M The module in which we're resolving the header directive. |
||
| 344 | /// \param Header The header directive to resolve. |
||
| 345 | /// \param NeedsFramework If M is not a framework but a missing header would |
||
| 346 | /// be found in case M was, set it to true. False otherwise. |
||
| 347 | void resolveHeader(Module *M, const Module::UnresolvedHeaderDirective &Header, |
||
| 348 | bool &NeedsFramework); |
||
| 349 | |||
| 350 | /// Attempt to resolve the specified header directive as naming a builtin |
||
| 351 | /// header. |
||
| 352 | /// \return \c true if a corresponding builtin header was found. |
||
| 353 | bool resolveAsBuiltinHeader(Module *M, |
||
| 354 | const Module::UnresolvedHeaderDirective &Header); |
||
| 355 | |||
| 356 | /// Looks up the modules that \p File corresponds to. |
||
| 357 | /// |
||
| 358 | /// If \p File represents a builtin header within Clang's builtin include |
||
| 359 | /// directory, this also loads all of the module maps to see if it will get |
||
| 360 | /// associated with a specific module (e.g. in /usr/include). |
||
| 361 | HeadersMap::iterator findKnownHeader(const FileEntry *File); |
||
| 362 | |||
| 363 | /// Searches for a module whose umbrella directory contains \p File. |
||
| 364 | /// |
||
| 365 | /// \param File The header to search for. |
||
| 366 | /// |
||
| 367 | /// \param IntermediateDirs On success, contains the set of directories |
||
| 368 | /// searched before finding \p File. |
||
| 369 | KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File, |
||
| 370 | SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs); |
||
| 371 | |||
| 372 | /// Given that \p File is not in the Headers map, look it up within |
||
| 373 | /// umbrella directories and find or create a module for it. |
||
| 374 | KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File); |
||
| 375 | |||
| 376 | /// A convenience method to determine if \p File is (possibly nested) |
||
| 377 | /// in an umbrella directory. |
||
| 378 | bool isHeaderInUmbrellaDirs(const FileEntry *File) { |
||
| 379 | SmallVector<const DirectoryEntry *, 2> IntermediateDirs; |
||
| 380 | return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs)); |
||
| 381 | } |
||
| 382 | |||
| 383 | Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir, |
||
| 384 | Attributes Attrs, Module *Parent); |
||
| 385 | |||
| 386 | public: |
||
| 387 | /// Construct a new module map. |
||
| 388 | /// |
||
| 389 | /// \param SourceMgr The source manager used to find module files and headers. |
||
| 390 | /// This source manager should be shared with the header-search mechanism, |
||
| 391 | /// since they will refer to the same headers. |
||
| 392 | /// |
||
| 393 | /// \param Diags A diagnostic engine used for diagnostics. |
||
| 394 | /// |
||
| 395 | /// \param LangOpts Language options for this translation unit. |
||
| 396 | /// |
||
| 397 | /// \param Target The target for this translation unit. |
||
| 398 | ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, |
||
| 399 | const LangOptions &LangOpts, const TargetInfo *Target, |
||
| 400 | HeaderSearch &HeaderInfo); |
||
| 401 | |||
| 402 | /// Destroy the module map. |
||
| 403 | ~ModuleMap(); |
||
| 404 | |||
| 405 | /// Set the target information. |
||
| 406 | void setTarget(const TargetInfo &Target); |
||
| 407 | |||
| 408 | /// Set the directory that contains Clang-supplied include |
||
| 409 | /// files, such as our stdarg.h or tgmath.h. |
||
| 410 | void setBuiltinIncludeDir(const DirectoryEntry *Dir) { |
||
| 411 | BuiltinIncludeDir = Dir; |
||
| 412 | } |
||
| 413 | |||
| 414 | /// Get the directory that contains Clang-supplied include files. |
||
| 415 | const DirectoryEntry *getBuiltinDir() const { |
||
| 416 | return BuiltinIncludeDir; |
||
| 417 | } |
||
| 418 | |||
| 419 | /// Is this a compiler builtin header? |
||
| 420 | static bool isBuiltinHeader(StringRef FileName); |
||
| 421 | bool isBuiltinHeader(const FileEntry *File); |
||
| 422 | |||
| 423 | /// Add a module map callback. |
||
| 424 | void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) { |
||
| 425 | Callbacks.push_back(std::move(Callback)); |
||
| 426 | } |
||
| 427 | |||
| 428 | /// Retrieve the module that owns the given header file, if any. Note that |
||
| 429 | /// this does not implicitly load module maps, except for builtin headers, |
||
| 430 | /// and does not consult the external source. (Those checks are the |
||
| 431 | /// responsibility of \ref HeaderSearch.) |
||
| 432 | /// |
||
| 433 | /// \param File The header file that is likely to be included. |
||
| 434 | /// |
||
| 435 | /// \param AllowTextual If \c true and \p File is a textual header, return |
||
| 436 | /// its owning module. Otherwise, no KnownHeader will be returned if the |
||
| 437 | /// file is only known as a textual header. |
||
| 438 | /// |
||
| 439 | /// \returns The module KnownHeader, which provides the module that owns the |
||
| 440 | /// given header file. The KnownHeader is default constructed to indicate |
||
| 441 | /// that no module owns this header file. |
||
| 442 | KnownHeader findModuleForHeader(const FileEntry *File, |
||
| 443 | bool AllowTextual = false, |
||
| 444 | bool AllowExcluded = false); |
||
| 445 | |||
| 446 | /// Retrieve all the modules that contain the given header file. Note that |
||
| 447 | /// this does not implicitly load module maps, except for builtin headers, |
||
| 448 | /// and does not consult the external source. (Those checks are the |
||
| 449 | /// responsibility of \ref HeaderSearch.) |
||
| 450 | /// |
||
| 451 | /// Typically, \ref findModuleForHeader should be used instead, as it picks |
||
| 452 | /// the preferred module for the header. |
||
| 453 | ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File); |
||
| 454 | |||
| 455 | /// Like \ref findAllModulesForHeader, but do not attempt to infer module |
||
| 456 | /// ownership from umbrella headers if we've not already done so. |
||
| 457 | ArrayRef<KnownHeader> |
||
| 458 | findResolvedModulesForHeader(const FileEntry *File) const; |
||
| 459 | |||
| 460 | /// Resolve all lazy header directives for the specified file. |
||
| 461 | /// |
||
| 462 | /// This ensures that the HeaderFileInfo on HeaderSearch is up to date. This |
||
| 463 | /// is effectively internal, but is exposed so HeaderSearch can call it. |
||
| 464 | void resolveHeaderDirectives(const FileEntry *File) const; |
||
| 465 | |||
| 466 | /// Resolve lazy header directives for the specified module. If File is |
||
| 467 | /// provided, only headers with same size and modtime are resolved. If File |
||
| 468 | /// is not set, all headers are resolved. |
||
| 469 | void resolveHeaderDirectives(Module *Mod, |
||
| 470 | std::optional<const FileEntry *> File) const; |
||
| 471 | |||
| 472 | /// Reports errors if a module must not include a specific file. |
||
| 473 | /// |
||
| 474 | /// \param RequestingModule The module including a file. |
||
| 475 | /// |
||
| 476 | /// \param RequestingModuleIsModuleInterface \c true if the inclusion is in |
||
| 477 | /// the interface of RequestingModule, \c false if it's in the |
||
| 478 | /// implementation of RequestingModule. Value is ignored and |
||
| 479 | /// meaningless if RequestingModule is nullptr. |
||
| 480 | /// |
||
| 481 | /// \param FilenameLoc The location of the inclusion's filename. |
||
| 482 | /// |
||
| 483 | /// \param Filename The included filename as written. |
||
| 484 | /// |
||
| 485 | /// \param File The included file. |
||
| 486 | void diagnoseHeaderInclusion(Module *RequestingModule, |
||
| 487 | bool RequestingModuleIsModuleInterface, |
||
| 488 | SourceLocation FilenameLoc, StringRef Filename, |
||
| 489 | FileEntryRef File); |
||
| 490 | |||
| 491 | /// Determine whether the given header is part of a module |
||
| 492 | /// marked 'unavailable'. |
||
| 493 | bool isHeaderInUnavailableModule(const FileEntry *Header) const; |
||
| 494 | |||
| 495 | /// Determine whether the given header is unavailable as part |
||
| 496 | /// of the specified module. |
||
| 497 | bool isHeaderUnavailableInModule(const FileEntry *Header, |
||
| 498 | const Module *RequestingModule) const; |
||
| 499 | |||
| 500 | /// Retrieve a module with the given name. |
||
| 501 | /// |
||
| 502 | /// \param Name The name of the module to look up. |
||
| 503 | /// |
||
| 504 | /// \returns The named module, if known; otherwise, returns null. |
||
| 505 | Module *findModule(StringRef Name) const; |
||
| 506 | |||
| 507 | /// Retrieve a module with the given name using lexical name lookup, |
||
| 508 | /// starting at the given context. |
||
| 509 | /// |
||
| 510 | /// \param Name The name of the module to look up. |
||
| 511 | /// |
||
| 512 | /// \param Context The module context, from which we will perform lexical |
||
| 513 | /// name lookup. |
||
| 514 | /// |
||
| 515 | /// \returns The named module, if known; otherwise, returns null. |
||
| 516 | Module *lookupModuleUnqualified(StringRef Name, Module *Context) const; |
||
| 517 | |||
| 518 | /// Retrieve a module with the given name within the given context, |
||
| 519 | /// using direct (qualified) name lookup. |
||
| 520 | /// |
||
| 521 | /// \param Name The name of the module to look up. |
||
| 522 | /// |
||
| 523 | /// \param Context The module for which we will look for a submodule. If |
||
| 524 | /// null, we will look for a top-level module. |
||
| 525 | /// |
||
| 526 | /// \returns The named submodule, if known; otherwose, returns null. |
||
| 527 | Module *lookupModuleQualified(StringRef Name, Module *Context) const; |
||
| 528 | |||
| 529 | /// Find a new module or submodule, or create it if it does not already |
||
| 530 | /// exist. |
||
| 531 | /// |
||
| 532 | /// \param Name The name of the module to find or create. |
||
| 533 | /// |
||
| 534 | /// \param Parent The module that will act as the parent of this submodule, |
||
| 535 | /// or nullptr to indicate that this is a top-level module. |
||
| 536 | /// |
||
| 537 | /// \param IsFramework Whether this is a framework module. |
||
| 538 | /// |
||
| 539 | /// \param IsExplicit Whether this is an explicit submodule. |
||
| 540 | /// |
||
| 541 | /// \returns The found or newly-created module, along with a boolean value |
||
| 542 | /// that will be true if the module is newly-created. |
||
| 543 | std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, |
||
| 544 | bool IsFramework, |
||
| 545 | bool IsExplicit); |
||
| 546 | |||
| 547 | /// Create a global module fragment for a C++ module unit. |
||
| 548 | /// |
||
| 549 | /// We model the global module fragment as a submodule of the module |
||
| 550 | /// interface unit. Unfortunately, we can't create the module interface |
||
| 551 | /// unit's Module until later, because we don't know what it will be called |
||
| 552 | /// usually. See C++20 [module.unit]/7.2 for the case we could know its |
||
| 553 | /// parent. |
||
| 554 | Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, |
||
| 555 | Module *Parent = nullptr); |
||
| 556 | |||
| 557 | /// Create a global module fragment for a C++ module interface unit. |
||
| 558 | Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent, |
||
| 559 | SourceLocation Loc); |
||
| 560 | |||
| 561 | /// Create a new module for a C++ module interface unit. |
||
| 562 | /// The module must not already exist, and will be configured for the current |
||
| 563 | /// compilation. |
||
| 564 | /// |
||
| 565 | /// Note that this also sets the current module to the newly-created module. |
||
| 566 | /// |
||
| 567 | /// \returns The newly-created module. |
||
| 568 | Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name); |
||
| 569 | |||
| 570 | /// Create a C++20 header unit. |
||
| 571 | Module *createHeaderUnit(SourceLocation Loc, StringRef Name, |
||
| 572 | Module::Header H); |
||
| 573 | |||
| 574 | /// Infer the contents of a framework module map from the given |
||
| 575 | /// framework directory. |
||
| 576 | Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir, |
||
| 577 | bool IsSystem, Module *Parent); |
||
| 578 | |||
| 579 | /// Create a new top-level module that is shadowed by |
||
| 580 | /// \p ShadowingModule. |
||
| 581 | Module *createShadowedModule(StringRef Name, bool IsFramework, |
||
| 582 | Module *ShadowingModule); |
||
| 583 | |||
| 584 | /// Creates a new declaration scope for module names, allowing |
||
| 585 | /// previously defined modules to shadow definitions from the new scope. |
||
| 586 | /// |
||
| 587 | /// \note Module names from earlier scopes will shadow names from the new |
||
| 588 | /// scope, which is the opposite of how shadowing works for variables. |
||
| 589 | void finishModuleDeclarationScope() { CurrentModuleScopeID += 1; } |
||
| 590 | |||
| 591 | bool mayShadowNewModule(Module *ExistingModule) { |
||
| 592 | assert(!ExistingModule->Parent && "expected top-level module"); |
||
| 593 | assert(ModuleScopeIDs.count(ExistingModule) && "unknown module"); |
||
| 594 | return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID; |
||
| 595 | } |
||
| 596 | |||
| 597 | /// Check whether a framework module can be inferred in the given directory. |
||
| 598 | bool canInferFrameworkModule(const DirectoryEntry *Dir) const { |
||
| 599 | auto It = InferredDirectories.find(Dir); |
||
| 600 | return It != InferredDirectories.end() && It->getSecond().InferModules; |
||
| 601 | } |
||
| 602 | |||
| 603 | /// Retrieve the module map file containing the definition of the given |
||
| 604 | /// module. |
||
| 605 | /// |
||
| 606 | /// \param Module The module whose module map file will be returned, if known. |
||
| 607 | /// |
||
| 608 | /// \returns The file entry for the module map file containing the given |
||
| 609 | /// module, or nullptr if the module definition was inferred. |
||
| 610 | OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const; |
||
| 611 | |||
| 612 | /// Get the module map file that (along with the module name) uniquely |
||
| 613 | /// identifies this module. |
||
| 614 | /// |
||
| 615 | /// The particular module that \c Name refers to may depend on how the module |
||
| 616 | /// was found in header search. However, the combination of \c Name and |
||
| 617 | /// this module map will be globally unique for top-level modules. In the case |
||
| 618 | /// of inferred modules, returns the module map that allowed the inference |
||
| 619 | /// (e.g. contained 'module *'). Otherwise, returns |
||
| 620 | /// getContainingModuleMapFile(). |
||
| 621 | OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const; |
||
| 622 | |||
| 623 | void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap); |
||
| 624 | |||
| 625 | /// Canonicalize \p Path in a manner suitable for a module map file. In |
||
| 626 | /// particular, this canonicalizes the parent directory separately from the |
||
| 627 | /// filename so that it does not affect header resolution relative to the |
||
| 628 | /// modulemap. |
||
| 629 | /// |
||
| 630 | /// \returns an error code if any filesystem operations failed. In this case |
||
| 631 | /// \p Path is not modified. |
||
| 632 | std::error_code canonicalizeModuleMapPath(SmallVectorImpl<char> &Path); |
||
| 633 | |||
| 634 | /// Get any module map files other than getModuleMapFileForUniquing(M) |
||
| 635 | /// that define submodules of a top-level module \p M. This is cheaper than |
||
| 636 | /// getting the module map file for each submodule individually, since the |
||
| 637 | /// expected number of results is very small. |
||
| 638 | AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) { |
||
| 639 | auto I = AdditionalModMaps.find(M); |
||
| 640 | if (I == AdditionalModMaps.end()) |
||
| 641 | return nullptr; |
||
| 642 | return &I->second; |
||
| 643 | } |
||
| 644 | |||
| 645 | void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap); |
||
| 646 | |||
| 647 | /// Resolve all of the unresolved exports in the given module. |
||
| 648 | /// |
||
| 649 | /// \param Mod The module whose exports should be resolved. |
||
| 650 | /// |
||
| 651 | /// \param Complain Whether to emit diagnostics for failures. |
||
| 652 | /// |
||
| 653 | /// \returns true if any errors were encountered while resolving exports, |
||
| 654 | /// false otherwise. |
||
| 655 | bool resolveExports(Module *Mod, bool Complain); |
||
| 656 | |||
| 657 | /// Resolve all of the unresolved uses in the given module. |
||
| 658 | /// |
||
| 659 | /// \param Mod The module whose uses should be resolved. |
||
| 660 | /// |
||
| 661 | /// \param Complain Whether to emit diagnostics for failures. |
||
| 662 | /// |
||
| 663 | /// \returns true if any errors were encountered while resolving uses, |
||
| 664 | /// false otherwise. |
||
| 665 | bool resolveUses(Module *Mod, bool Complain); |
||
| 666 | |||
| 667 | /// Resolve all of the unresolved conflicts in the given module. |
||
| 668 | /// |
||
| 669 | /// \param Mod The module whose conflicts should be resolved. |
||
| 670 | /// |
||
| 671 | /// \param Complain Whether to emit diagnostics for failures. |
||
| 672 | /// |
||
| 673 | /// \returns true if any errors were encountered while resolving conflicts, |
||
| 674 | /// false otherwise. |
||
| 675 | bool resolveConflicts(Module *Mod, bool Complain); |
||
| 676 | |||
| 677 | /// Sets the umbrella header of the given module to the given |
||
| 678 | /// header. |
||
| 679 | void setUmbrellaHeader(Module *Mod, FileEntryRef UmbrellaHeader, |
||
| 680 | const Twine &NameAsWritten, |
||
| 681 | const Twine &PathRelativeToRootModuleDirectory); |
||
| 682 | |||
| 683 | /// Sets the umbrella directory of the given module to the given |
||
| 684 | /// directory. |
||
| 685 | void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, |
||
| 686 | const Twine &NameAsWritten, |
||
| 687 | const Twine &PathRelativeToRootModuleDirectory); |
||
| 688 | |||
| 689 | /// Adds this header to the given module. |
||
| 690 | /// \param Role The role of the header wrt the module. |
||
| 691 | void addHeader(Module *Mod, Module::Header Header, |
||
| 692 | ModuleHeaderRole Role, bool Imported = false); |
||
| 693 | |||
| 694 | /// Parse the given module map file, and record any modules we |
||
| 695 | /// encounter. |
||
| 696 | /// |
||
| 697 | /// \param File The file to be parsed. |
||
| 698 | /// |
||
| 699 | /// \param IsSystem Whether this module map file is in a system header |
||
| 700 | /// directory, and therefore should be considered a system module. |
||
| 701 | /// |
||
| 702 | /// \param HomeDir The directory in which relative paths within this module |
||
| 703 | /// map file will be resolved. |
||
| 704 | /// |
||
| 705 | /// \param ID The FileID of the file to process, if we've already entered it. |
||
| 706 | /// |
||
| 707 | /// \param Offset [inout] On input the offset at which to start parsing. On |
||
| 708 | /// output, the offset at which the module map terminated. |
||
| 709 | /// |
||
| 710 | /// \param ExternModuleLoc The location of the "extern module" declaration |
||
| 711 | /// that caused us to load this module map file, if any. |
||
| 712 | /// |
||
| 713 | /// \returns true if an error occurred, false otherwise. |
||
| 714 | bool parseModuleMapFile(const FileEntry *File, bool IsSystem, |
||
| 715 | const DirectoryEntry *HomeDir, |
||
| 716 | FileID ID = FileID(), unsigned *Offset = nullptr, |
||
| 717 | SourceLocation ExternModuleLoc = SourceLocation()); |
||
| 718 | |||
| 719 | /// Dump the contents of the module map, for debugging purposes. |
||
| 720 | void dump(); |
||
| 721 | |||
| 722 | using module_iterator = llvm::StringMap<Module *>::const_iterator; |
||
| 723 | |||
| 724 | module_iterator module_begin() const { return Modules.begin(); } |
||
| 725 | module_iterator module_end() const { return Modules.end(); } |
||
| 726 | llvm::iterator_range<module_iterator> modules() const { |
||
| 727 | return {module_begin(), module_end()}; |
||
| 728 | } |
||
| 729 | |||
| 730 | /// Cache a module load. M might be nullptr. |
||
| 731 | void cacheModuleLoad(const IdentifierInfo &II, Module *M) { |
||
| 732 | CachedModuleLoads[&II] = M; |
||
| 733 | } |
||
| 734 | |||
| 735 | /// Return a cached module load. |
||
| 736 | std::optional<Module *> getCachedModuleLoad(const IdentifierInfo &II) { |
||
| 737 | auto I = CachedModuleLoads.find(&II); |
||
| 738 | if (I == CachedModuleLoads.end()) |
||
| 739 | return std::nullopt; |
||
| 740 | return I->second; |
||
| 741 | } |
||
| 742 | }; |
||
| 743 | |||
| 744 | } // namespace clang |
||
| 745 | |||
| 746 | #endif // LLVM_CLANG_LEX_MODULEMAP_H |