Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- Module.h - Describe a module -----------------------------*- 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 | /// \file |
||
| 10 | /// Defines the clang::Module class, which describes a module in the |
||
| 11 | /// source code. |
||
| 12 | // |
||
| 13 | //===----------------------------------------------------------------------===// |
||
| 14 | |||
| 15 | #ifndef LLVM_CLANG_BASIC_MODULE_H |
||
| 16 | #define LLVM_CLANG_BASIC_MODULE_H |
||
| 17 | |||
| 18 | #include "clang/Basic/DirectoryEntry.h" |
||
| 19 | #include "clang/Basic/FileEntry.h" |
||
| 20 | #include "clang/Basic/SourceLocation.h" |
||
| 21 | #include "llvm/ADT/ArrayRef.h" |
||
| 22 | #include "llvm/ADT/DenseSet.h" |
||
| 23 | #include "llvm/ADT/PointerIntPair.h" |
||
| 24 | #include "llvm/ADT/STLExtras.h" |
||
| 25 | #include "llvm/ADT/SetVector.h" |
||
| 26 | #include "llvm/ADT/SmallVector.h" |
||
| 27 | #include "llvm/ADT/StringMap.h" |
||
| 28 | #include "llvm/ADT/StringRef.h" |
||
| 29 | #include "llvm/ADT/iterator_range.h" |
||
| 30 | #include <array> |
||
| 31 | #include <cassert> |
||
| 32 | #include <cstdint> |
||
| 33 | #include <ctime> |
||
| 34 | #include <iterator> |
||
| 35 | #include <optional> |
||
| 36 | #include <string> |
||
| 37 | #include <utility> |
||
| 38 | #include <vector> |
||
| 39 | |||
| 40 | namespace llvm { |
||
| 41 | |||
| 42 | class raw_ostream; |
||
| 43 | |||
| 44 | } // namespace llvm |
||
| 45 | |||
| 46 | namespace clang { |
||
| 47 | |||
| 48 | class FileManager; |
||
| 49 | class LangOptions; |
||
| 50 | class TargetInfo; |
||
| 51 | |||
| 52 | /// Describes the name of a module. |
||
| 53 | using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; |
||
| 54 | |||
| 55 | /// The signature of a module, which is a hash of the AST content. |
||
| 56 | struct ASTFileSignature : std::array<uint8_t, 20> { |
||
| 57 | using BaseT = std::array<uint8_t, 20>; |
||
| 58 | |||
| 59 | static constexpr size_t size = std::tuple_size<BaseT>::value; |
||
| 60 | |||
| 61 | ASTFileSignature(BaseT S = {{0}}) : BaseT(std::move(S)) {} |
||
| 62 | |||
| 63 | explicit operator bool() const { return *this != BaseT({{0}}); } |
||
| 64 | |||
| 65 | /// Returns the value truncated to the size of an uint64_t. |
||
| 66 | uint64_t truncatedValue() const { |
||
| 67 | uint64_t Value = 0; |
||
| 68 | static_assert(sizeof(*this) >= sizeof(uint64_t), "No need to truncate."); |
||
| 69 | for (unsigned I = 0; I < sizeof(uint64_t); ++I) |
||
| 70 | Value |= static_cast<uint64_t>((*this)[I]) << (I * 8); |
||
| 71 | return Value; |
||
| 72 | } |
||
| 73 | |||
| 74 | static ASTFileSignature create(std::array<uint8_t, 20> Bytes) { |
||
| 75 | return ASTFileSignature(std::move(Bytes)); |
||
| 76 | } |
||
| 77 | |||
| 78 | static ASTFileSignature createDISentinel() { |
||
| 79 | ASTFileSignature Sentinel; |
||
| 80 | Sentinel.fill(0xFF); |
||
| 81 | return Sentinel; |
||
| 82 | } |
||
| 83 | |||
| 84 | template <typename InputIt> |
||
| 85 | static ASTFileSignature create(InputIt First, InputIt Last) { |
||
| 86 | assert(std::distance(First, Last) == size && |
||
| 87 | "Wrong amount of bytes to create an ASTFileSignature"); |
||
| 88 | |||
| 89 | ASTFileSignature Signature; |
||
| 90 | std::copy(First, Last, Signature.begin()); |
||
| 91 | return Signature; |
||
| 92 | } |
||
| 93 | }; |
||
| 94 | |||
| 95 | /// Describes a module or submodule. |
||
| 96 | /// |
||
| 97 | /// Aligned to 8 bytes to allow for llvm::PointerIntPair<Module *, 3>. |
||
| 98 | class alignas(8) Module { |
||
| 99 | public: |
||
| 100 | /// The name of this module. |
||
| 101 | std::string Name; |
||
| 102 | |||
| 103 | /// The location of the module definition. |
||
| 104 | SourceLocation DefinitionLoc; |
||
| 105 | |||
| 106 | enum ModuleKind { |
||
| 107 | /// This is a module that was defined by a module map and built out |
||
| 108 | /// of header files. |
||
| 109 | ModuleMapModule, |
||
| 110 | |||
| 111 | /// This is a C++20 module interface unit. |
||
| 112 | ModuleInterfaceUnit, |
||
| 113 | |||
| 114 | /// This is a C++ 20 header unit. |
||
| 115 | ModuleHeaderUnit, |
||
| 116 | |||
| 117 | /// This is a C++ 20 module partition interface. |
||
| 118 | ModulePartitionInterface, |
||
| 119 | |||
| 120 | /// This is a C++ 20 module partition implementation. |
||
| 121 | ModulePartitionImplementation, |
||
| 122 | |||
| 123 | /// This is a fragment of the global module within some C++ module. |
||
| 124 | GlobalModuleFragment, |
||
| 125 | |||
| 126 | /// This is the private module fragment within some C++ module. |
||
| 127 | PrivateModuleFragment, |
||
| 128 | }; |
||
| 129 | |||
| 130 | /// The kind of this module. |
||
| 131 | ModuleKind Kind = ModuleMapModule; |
||
| 132 | |||
| 133 | /// The parent of this module. This will be NULL for the top-level |
||
| 134 | /// module. |
||
| 135 | Module *Parent; |
||
| 136 | |||
| 137 | /// The build directory of this module. This is the directory in |
||
| 138 | /// which the module is notionally built, and relative to which its headers |
||
| 139 | /// are found. |
||
| 140 | const DirectoryEntry *Directory = nullptr; |
||
| 141 | |||
| 142 | /// The presumed file name for the module map defining this module. |
||
| 143 | /// Only non-empty when building from preprocessed source. |
||
| 144 | std::string PresumedModuleMapFile; |
||
| 145 | |||
| 146 | /// The umbrella header or directory. |
||
| 147 | llvm::PointerUnion<const FileEntryRef::MapEntry *, const DirectoryEntry *> |
||
| 148 | Umbrella; |
||
| 149 | |||
| 150 | /// The module signature. |
||
| 151 | ASTFileSignature Signature; |
||
| 152 | |||
| 153 | /// The name of the umbrella entry, as written in the module map. |
||
| 154 | std::string UmbrellaAsWritten; |
||
| 155 | |||
| 156 | // The path to the umbrella entry relative to the root module's \c Directory. |
||
| 157 | std::string UmbrellaRelativeToRootModuleDirectory; |
||
| 158 | |||
| 159 | /// The module through which entities defined in this module will |
||
| 160 | /// eventually be exposed, for use in "private" modules. |
||
| 161 | std::string ExportAsModule; |
||
| 162 | |||
| 163 | /// Does this Module scope describe part of the purview of a standard named |
||
| 164 | /// C++ module? |
||
| 165 | bool isModulePurview() const { |
||
| 166 | return Kind == ModuleInterfaceUnit || Kind == ModulePartitionInterface || |
||
| 167 | Kind == ModulePartitionImplementation || |
||
| 168 | Kind == PrivateModuleFragment; |
||
| 169 | } |
||
| 170 | |||
| 171 | /// Does this Module scope describe a fragment of the global module within |
||
| 172 | /// some C++ module. |
||
| 173 | bool isGlobalModule() const { return Kind == GlobalModuleFragment; } |
||
| 174 | |||
| 175 | bool isPrivateModule() const { return Kind == PrivateModuleFragment; } |
||
| 176 | |||
| 177 | bool isModuleMapModule() const { return Kind == ModuleMapModule; } |
||
| 178 | |||
| 179 | private: |
||
| 180 | /// The submodules of this module, indexed by name. |
||
| 181 | std::vector<Module *> SubModules; |
||
| 182 | |||
| 183 | /// A mapping from the submodule name to the index into the |
||
| 184 | /// \c SubModules vector at which that submodule resides. |
||
| 185 | llvm::StringMap<unsigned> SubModuleIndex; |
||
| 186 | |||
| 187 | /// The AST file if this is a top-level module which has a |
||
| 188 | /// corresponding serialized AST file, or null otherwise. |
||
| 189 | OptionalFileEntryRef ASTFile; |
||
| 190 | |||
| 191 | /// The top-level headers associated with this module. |
||
| 192 | llvm::SmallSetVector<const FileEntry *, 2> TopHeaders; |
||
| 193 | |||
| 194 | /// top-level header filenames that aren't resolved to FileEntries yet. |
||
| 195 | std::vector<std::string> TopHeaderNames; |
||
| 196 | |||
| 197 | /// Cache of modules visible to lookup in this module. |
||
| 198 | mutable llvm::DenseSet<const Module*> VisibleModulesCache; |
||
| 199 | |||
| 200 | /// The ID used when referencing this module within a VisibleModuleSet. |
||
| 201 | unsigned VisibilityID; |
||
| 202 | |||
| 203 | public: |
||
| 204 | enum HeaderKind { |
||
| 205 | HK_Normal, |
||
| 206 | HK_Textual, |
||
| 207 | HK_Private, |
||
| 208 | HK_PrivateTextual, |
||
| 209 | HK_Excluded |
||
| 210 | }; |
||
| 211 | static const int NumHeaderKinds = HK_Excluded + 1; |
||
| 212 | |||
| 213 | /// Information about a header directive as found in the module map |
||
| 214 | /// file. |
||
| 215 | struct Header { |
||
| 216 | std::string NameAsWritten; |
||
| 217 | std::string PathRelativeToRootModuleDirectory; |
||
| 218 | OptionalFileEntryRefDegradesToFileEntryPtr Entry; |
||
| 219 | |||
| 220 | explicit operator bool() { return Entry.has_value(); } |
||
| 221 | }; |
||
| 222 | |||
| 223 | /// Information about a directory name as found in the module map |
||
| 224 | /// file. |
||
| 225 | struct DirectoryName { |
||
| 226 | std::string NameAsWritten; |
||
| 227 | std::string PathRelativeToRootModuleDirectory; |
||
| 228 | const DirectoryEntry *Entry; |
||
| 229 | |||
| 230 | explicit operator bool() { return Entry; } |
||
| 231 | }; |
||
| 232 | |||
| 233 | /// The headers that are part of this module. |
||
| 234 | SmallVector<Header, 2> Headers[5]; |
||
| 235 | |||
| 236 | /// Stored information about a header directive that was found in the |
||
| 237 | /// module map file but has not been resolved to a file. |
||
| 238 | struct UnresolvedHeaderDirective { |
||
| 239 | HeaderKind Kind = HK_Normal; |
||
| 240 | SourceLocation FileNameLoc; |
||
| 241 | std::string FileName; |
||
| 242 | bool IsUmbrella = false; |
||
| 243 | bool HasBuiltinHeader = false; |
||
| 244 | std::optional<off_t> Size; |
||
| 245 | std::optional<time_t> ModTime; |
||
| 246 | }; |
||
| 247 | |||
| 248 | /// Headers that are mentioned in the module map file but that we have not |
||
| 249 | /// yet attempted to resolve to a file on the file system. |
||
| 250 | SmallVector<UnresolvedHeaderDirective, 1> UnresolvedHeaders; |
||
| 251 | |||
| 252 | /// Headers that are mentioned in the module map file but could not be |
||
| 253 | /// found on the file system. |
||
| 254 | SmallVector<UnresolvedHeaderDirective, 1> MissingHeaders; |
||
| 255 | |||
| 256 | /// An individual requirement: a feature name and a flag indicating |
||
| 257 | /// the required state of that feature. |
||
| 258 | using Requirement = std::pair<std::string, bool>; |
||
| 259 | |||
| 260 | /// The set of language features required to use this module. |
||
| 261 | /// |
||
| 262 | /// If any of these requirements are not available, the \c IsAvailable bit |
||
| 263 | /// will be false to indicate that this (sub)module is not available. |
||
| 264 | SmallVector<Requirement, 2> Requirements; |
||
| 265 | |||
| 266 | /// A module with the same name that shadows this module. |
||
| 267 | Module *ShadowingModule = nullptr; |
||
| 268 | |||
| 269 | /// Whether this module has declared itself unimportable, either because |
||
| 270 | /// it's missing a requirement from \p Requirements or because it's been |
||
| 271 | /// shadowed by another module. |
||
| 272 | unsigned IsUnimportable : 1; |
||
| 273 | |||
| 274 | /// Whether we tried and failed to load a module file for this module. |
||
| 275 | unsigned HasIncompatibleModuleFile : 1; |
||
| 276 | |||
| 277 | /// Whether this module is available in the current translation unit. |
||
| 278 | /// |
||
| 279 | /// If the module is missing headers or does not meet all requirements then |
||
| 280 | /// this bit will be 0. |
||
| 281 | unsigned IsAvailable : 1; |
||
| 282 | |||
| 283 | /// Whether this module was loaded from a module file. |
||
| 284 | unsigned IsFromModuleFile : 1; |
||
| 285 | |||
| 286 | /// Whether this is a framework module. |
||
| 287 | unsigned IsFramework : 1; |
||
| 288 | |||
| 289 | /// Whether this is an explicit submodule. |
||
| 290 | unsigned IsExplicit : 1; |
||
| 291 | |||
| 292 | /// Whether this is a "system" module (which assumes that all |
||
| 293 | /// headers in it are system headers). |
||
| 294 | unsigned IsSystem : 1; |
||
| 295 | |||
| 296 | /// Whether this is an 'extern "C"' module (which implicitly puts all |
||
| 297 | /// headers in it within an 'extern "C"' block, and allows the module to be |
||
| 298 | /// imported within such a block). |
||
| 299 | unsigned IsExternC : 1; |
||
| 300 | |||
| 301 | /// Whether this is an inferred submodule (module * { ... }). |
||
| 302 | unsigned IsInferred : 1; |
||
| 303 | |||
| 304 | /// Whether we should infer submodules for this module based on |
||
| 305 | /// the headers. |
||
| 306 | /// |
||
| 307 | /// Submodules can only be inferred for modules with an umbrella header. |
||
| 308 | unsigned InferSubmodules : 1; |
||
| 309 | |||
| 310 | /// Whether, when inferring submodules, the inferred submodules |
||
| 311 | /// should be explicit. |
||
| 312 | unsigned InferExplicitSubmodules : 1; |
||
| 313 | |||
| 314 | /// Whether, when inferring submodules, the inferr submodules should |
||
| 315 | /// export all modules they import (e.g., the equivalent of "export *"). |
||
| 316 | unsigned InferExportWildcard : 1; |
||
| 317 | |||
| 318 | /// Whether the set of configuration macros is exhaustive. |
||
| 319 | /// |
||
| 320 | /// When the set of configuration macros is exhaustive, meaning |
||
| 321 | /// that no identifier not in this list should affect how the module is |
||
| 322 | /// built. |
||
| 323 | unsigned ConfigMacrosExhaustive : 1; |
||
| 324 | |||
| 325 | /// Whether files in this module can only include non-modular headers |
||
| 326 | /// and headers from used modules. |
||
| 327 | unsigned NoUndeclaredIncludes : 1; |
||
| 328 | |||
| 329 | /// Whether this module came from a "private" module map, found next |
||
| 330 | /// to a regular (public) module map. |
||
| 331 | unsigned ModuleMapIsPrivate : 1; |
||
| 332 | |||
| 333 | /// Describes the visibility of the various names within a |
||
| 334 | /// particular module. |
||
| 335 | enum NameVisibilityKind { |
||
| 336 | /// All of the names in this module are hidden. |
||
| 337 | Hidden, |
||
| 338 | /// All of the names in this module are visible. |
||
| 339 | AllVisible |
||
| 340 | }; |
||
| 341 | |||
| 342 | /// The visibility of names within this particular module. |
||
| 343 | NameVisibilityKind NameVisibility; |
||
| 344 | |||
| 345 | /// The location of the inferred submodule. |
||
| 346 | SourceLocation InferredSubmoduleLoc; |
||
| 347 | |||
| 348 | /// The set of modules imported by this module, and on which this |
||
| 349 | /// module depends. |
||
| 350 | llvm::SmallSetVector<Module *, 2> Imports; |
||
| 351 | |||
| 352 | /// The set of top-level modules that affected the compilation of this module, |
||
| 353 | /// but were not imported. |
||
| 354 | llvm::SmallSetVector<Module *, 2> AffectingClangModules; |
||
| 355 | |||
| 356 | /// Describes an exported module. |
||
| 357 | /// |
||
| 358 | /// The pointer is the module being re-exported, while the bit will be true |
||
| 359 | /// to indicate that this is a wildcard export. |
||
| 360 | using ExportDecl = llvm::PointerIntPair<Module *, 1, bool>; |
||
| 361 | |||
| 362 | /// The set of export declarations. |
||
| 363 | SmallVector<ExportDecl, 2> Exports; |
||
| 364 | |||
| 365 | /// Describes an exported module that has not yet been resolved |
||
| 366 | /// (perhaps because the module it refers to has not yet been loaded). |
||
| 367 | struct UnresolvedExportDecl { |
||
| 368 | /// The location of the 'export' keyword in the module map file. |
||
| 369 | SourceLocation ExportLoc; |
||
| 370 | |||
| 371 | /// The name of the module. |
||
| 372 | ModuleId Id; |
||
| 373 | |||
| 374 | /// Whether this export declaration ends in a wildcard, indicating |
||
| 375 | /// that all of its submodules should be exported (rather than the named |
||
| 376 | /// module itself). |
||
| 377 | bool Wildcard; |
||
| 378 | }; |
||
| 379 | |||
| 380 | /// The set of export declarations that have yet to be resolved. |
||
| 381 | SmallVector<UnresolvedExportDecl, 2> UnresolvedExports; |
||
| 382 | |||
| 383 | /// The directly used modules. |
||
| 384 | SmallVector<Module *, 2> DirectUses; |
||
| 385 | |||
| 386 | /// The set of use declarations that have yet to be resolved. |
||
| 387 | SmallVector<ModuleId, 2> UnresolvedDirectUses; |
||
| 388 | |||
| 389 | /// When \c NoUndeclaredIncludes is true, the set of modules this module tried |
||
| 390 | /// to import but didn't because they are not direct uses. |
||
| 391 | llvm::SmallSetVector<const Module *, 2> UndeclaredUses; |
||
| 392 | |||
| 393 | /// A library or framework to link against when an entity from this |
||
| 394 | /// module is used. |
||
| 395 | struct LinkLibrary { |
||
| 396 | LinkLibrary() = default; |
||
| 397 | LinkLibrary(const std::string &Library, bool IsFramework) |
||
| 398 | : Library(Library), IsFramework(IsFramework) {} |
||
| 399 | |||
| 400 | /// The library to link against. |
||
| 401 | /// |
||
| 402 | /// This will typically be a library or framework name, but can also |
||
| 403 | /// be an absolute path to the library or framework. |
||
| 404 | std::string Library; |
||
| 405 | |||
| 406 | /// Whether this is a framework rather than a library. |
||
| 407 | bool IsFramework = false; |
||
| 408 | }; |
||
| 409 | |||
| 410 | /// The set of libraries or frameworks to link against when |
||
| 411 | /// an entity from this module is used. |
||
| 412 | llvm::SmallVector<LinkLibrary, 2> LinkLibraries; |
||
| 413 | |||
| 414 | /// Autolinking uses the framework name for linking purposes |
||
| 415 | /// when this is false and the export_as name otherwise. |
||
| 416 | bool UseExportAsModuleLinkName = false; |
||
| 417 | |||
| 418 | /// The set of "configuration macros", which are macros that |
||
| 419 | /// (intentionally) change how this module is built. |
||
| 420 | std::vector<std::string> ConfigMacros; |
||
| 421 | |||
| 422 | /// An unresolved conflict with another module. |
||
| 423 | struct UnresolvedConflict { |
||
| 424 | /// The (unresolved) module id. |
||
| 425 | ModuleId Id; |
||
| 426 | |||
| 427 | /// The message provided to the user when there is a conflict. |
||
| 428 | std::string Message; |
||
| 429 | }; |
||
| 430 | |||
| 431 | /// The list of conflicts for which the module-id has not yet been |
||
| 432 | /// resolved. |
||
| 433 | std::vector<UnresolvedConflict> UnresolvedConflicts; |
||
| 434 | |||
| 435 | /// A conflict between two modules. |
||
| 436 | struct Conflict { |
||
| 437 | /// The module that this module conflicts with. |
||
| 438 | Module *Other; |
||
| 439 | |||
| 440 | /// The message provided to the user when there is a conflict. |
||
| 441 | std::string Message; |
||
| 442 | }; |
||
| 443 | |||
| 444 | /// The list of conflicts. |
||
| 445 | std::vector<Conflict> Conflicts; |
||
| 446 | |||
| 447 | /// Construct a new module or submodule. |
||
| 448 | Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, |
||
| 449 | bool IsFramework, bool IsExplicit, unsigned VisibilityID); |
||
| 450 | |||
| 451 | ~Module(); |
||
| 452 | |||
| 453 | /// Determine whether this module has been declared unimportable. |
||
| 454 | bool isUnimportable() const { return IsUnimportable; } |
||
| 455 | |||
| 456 | /// Determine whether this module has been declared unimportable. |
||
| 457 | /// |
||
| 458 | /// \param LangOpts The language options used for the current |
||
| 459 | /// translation unit. |
||
| 460 | /// |
||
| 461 | /// \param Target The target options used for the current translation unit. |
||
| 462 | /// |
||
| 463 | /// \param Req If this module is unimportable because of a missing |
||
| 464 | /// requirement, this parameter will be set to one of the requirements that |
||
| 465 | /// is not met for use of this module. |
||
| 466 | /// |
||
| 467 | /// \param ShadowingModule If this module is unimportable because it is |
||
| 468 | /// shadowed, this parameter will be set to the shadowing module. |
||
| 469 | bool isUnimportable(const LangOptions &LangOpts, const TargetInfo &Target, |
||
| 470 | Requirement &Req, Module *&ShadowingModule) const; |
||
| 471 | |||
| 472 | /// Determine whether this module can be built in this compilation. |
||
| 473 | bool isForBuilding(const LangOptions &LangOpts) const; |
||
| 474 | |||
| 475 | /// Determine whether this module is available for use within the |
||
| 476 | /// current translation unit. |
||
| 477 | bool isAvailable() const { return IsAvailable; } |
||
| 478 | |||
| 479 | /// Determine whether this module is available for use within the |
||
| 480 | /// current translation unit. |
||
| 481 | /// |
||
| 482 | /// \param LangOpts The language options used for the current |
||
| 483 | /// translation unit. |
||
| 484 | /// |
||
| 485 | /// \param Target The target options used for the current translation unit. |
||
| 486 | /// |
||
| 487 | /// \param Req If this module is unavailable because of a missing requirement, |
||
| 488 | /// this parameter will be set to one of the requirements that is not met for |
||
| 489 | /// use of this module. |
||
| 490 | /// |
||
| 491 | /// \param MissingHeader If this module is unavailable because of a missing |
||
| 492 | /// header, this parameter will be set to one of the missing headers. |
||
| 493 | /// |
||
| 494 | /// \param ShadowingModule If this module is unavailable because it is |
||
| 495 | /// shadowed, this parameter will be set to the shadowing module. |
||
| 496 | bool isAvailable(const LangOptions &LangOpts, |
||
| 497 | const TargetInfo &Target, |
||
| 498 | Requirement &Req, |
||
| 499 | UnresolvedHeaderDirective &MissingHeader, |
||
| 500 | Module *&ShadowingModule) const; |
||
| 501 | |||
| 502 | /// Determine whether this module is a submodule. |
||
| 503 | bool isSubModule() const { return Parent != nullptr; } |
||
| 504 | |||
| 505 | /// Check if this module is a (possibly transitive) submodule of \p Other. |
||
| 506 | /// |
||
| 507 | /// The 'A is a submodule of B' relation is a partial order based on the |
||
| 508 | /// the parent-child relationship between individual modules. |
||
| 509 | /// |
||
| 510 | /// Returns \c false if \p Other is \c nullptr. |
||
| 511 | bool isSubModuleOf(const Module *Other) const; |
||
| 512 | |||
| 513 | /// Determine whether this module is a part of a framework, |
||
| 514 | /// either because it is a framework module or because it is a submodule |
||
| 515 | /// of a framework module. |
||
| 516 | bool isPartOfFramework() const { |
||
| 517 | for (const Module *Mod = this; Mod; Mod = Mod->Parent) |
||
| 518 | if (Mod->IsFramework) |
||
| 519 | return true; |
||
| 520 | |||
| 521 | return false; |
||
| 522 | } |
||
| 523 | |||
| 524 | /// Determine whether this module is a subframework of another |
||
| 525 | /// framework. |
||
| 526 | bool isSubFramework() const { |
||
| 527 | return IsFramework && Parent && Parent->isPartOfFramework(); |
||
| 528 | } |
||
| 529 | |||
| 530 | /// Set the parent of this module. This should only be used if the parent |
||
| 531 | /// could not be set during module creation. |
||
| 532 | void setParent(Module *M) { |
||
| 533 | assert(!Parent); |
||
| 534 | Parent = M; |
||
| 535 | Parent->SubModuleIndex[Name] = Parent->SubModules.size(); |
||
| 536 | Parent->SubModules.push_back(this); |
||
| 537 | } |
||
| 538 | |||
| 539 | /// Is this module have similar semantics as headers. |
||
| 540 | bool isHeaderLikeModule() const { |
||
| 541 | return isModuleMapModule() || isHeaderUnit(); |
||
| 542 | } |
||
| 543 | |||
| 544 | /// Is this a module partition. |
||
| 545 | bool isModulePartition() const { |
||
| 546 | return Kind == ModulePartitionInterface || |
||
| 547 | Kind == ModulePartitionImplementation; |
||
| 548 | } |
||
| 549 | |||
| 550 | /// Is this module a header unit. |
||
| 551 | bool isHeaderUnit() const { return Kind == ModuleHeaderUnit; } |
||
| 552 | // Is this a C++20 module interface or a partition. |
||
| 553 | bool isInterfaceOrPartition() const { |
||
| 554 | return Kind == ModuleInterfaceUnit || isModulePartition(); |
||
| 555 | } |
||
| 556 | |||
| 557 | bool isModuleInterfaceUnit() const { |
||
| 558 | return Kind == ModuleInterfaceUnit || Kind == ModulePartitionInterface; |
||
| 559 | } |
||
| 560 | |||
| 561 | /// Get the primary module interface name from a partition. |
||
| 562 | StringRef getPrimaryModuleInterfaceName() const { |
||
| 563 | // Technically, global module fragment belongs to global module. And global |
||
| 564 | // module has no name: [module.unit]p6: |
||
| 565 | // The global module has no name, no module interface unit, and is not |
||
| 566 | // introduced by any module-declaration. |
||
| 567 | // |
||
| 568 | // <global> is the default name showed in module map. |
||
| 569 | if (isGlobalModule()) |
||
| 570 | return "<global>"; |
||
| 571 | |||
| 572 | if (isModulePartition()) { |
||
| 573 | auto pos = Name.find(':'); |
||
| 574 | return StringRef(Name.data(), pos); |
||
| 575 | } |
||
| 576 | |||
| 577 | if (isPrivateModule()) |
||
| 578 | return getTopLevelModuleName(); |
||
| 579 | |||
| 580 | return Name; |
||
| 581 | } |
||
| 582 | |||
| 583 | /// Retrieve the full name of this module, including the path from |
||
| 584 | /// its top-level module. |
||
| 585 | /// \param AllowStringLiterals If \c true, components that might not be |
||
| 586 | /// lexically valid as identifiers will be emitted as string literals. |
||
| 587 | std::string getFullModuleName(bool AllowStringLiterals = false) const; |
||
| 588 | |||
| 589 | /// Whether the full name of this module is equal to joining |
||
| 590 | /// \p nameParts with "."s. |
||
| 591 | /// |
||
| 592 | /// This is more efficient than getFullModuleName(). |
||
| 593 | bool fullModuleNameIs(ArrayRef<StringRef> nameParts) const; |
||
| 594 | |||
| 595 | /// Retrieve the top-level module for this (sub)module, which may |
||
| 596 | /// be this module. |
||
| 597 | Module *getTopLevelModule() { |
||
| 598 | return const_cast<Module *>( |
||
| 599 | const_cast<const Module *>(this)->getTopLevelModule()); |
||
| 600 | } |
||
| 601 | |||
| 602 | /// Retrieve the top-level module for this (sub)module, which may |
||
| 603 | /// be this module. |
||
| 604 | const Module *getTopLevelModule() const; |
||
| 605 | |||
| 606 | /// Retrieve the name of the top-level module. |
||
| 607 | StringRef getTopLevelModuleName() const { |
||
| 608 | return getTopLevelModule()->Name; |
||
| 609 | } |
||
| 610 | |||
| 611 | /// The serialized AST file for this module, if one was created. |
||
| 612 | OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const { |
||
| 613 | return getTopLevelModule()->ASTFile; |
||
| 614 | } |
||
| 615 | |||
| 616 | /// Set the serialized AST file for the top-level module of this module. |
||
| 617 | void setASTFile(OptionalFileEntryRef File) { |
||
| 618 | assert((!getASTFile() || getASTFile() == File) && "file path changed"); |
||
| 619 | getTopLevelModule()->ASTFile = File; |
||
| 620 | } |
||
| 621 | |||
| 622 | /// Retrieve the directory for which this module serves as the |
||
| 623 | /// umbrella. |
||
| 624 | DirectoryName getUmbrellaDir() const; |
||
| 625 | |||
| 626 | /// Retrieve the header that serves as the umbrella header for this |
||
| 627 | /// module. |
||
| 628 | Header getUmbrellaHeader() const { |
||
| 629 | if (auto *ME = Umbrella.dyn_cast<const FileEntryRef::MapEntry *>()) |
||
| 630 | return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory, |
||
| 631 | FileEntryRef(*ME)}; |
||
| 632 | return Header{}; |
||
| 633 | } |
||
| 634 | |||
| 635 | /// Determine whether this module has an umbrella directory that is |
||
| 636 | /// not based on an umbrella header. |
||
| 637 | bool hasUmbrellaDir() const { |
||
| 638 | return Umbrella && Umbrella.is<const DirectoryEntry *>(); |
||
| 639 | } |
||
| 640 | |||
| 641 | /// Add a top-level header associated with this module. |
||
| 642 | void addTopHeader(const FileEntry *File); |
||
| 643 | |||
| 644 | /// Add a top-level header filename associated with this module. |
||
| 645 | void addTopHeaderFilename(StringRef Filename) { |
||
| 646 | TopHeaderNames.push_back(std::string(Filename)); |
||
| 647 | } |
||
| 648 | |||
| 649 | /// The top-level headers associated with this module. |
||
| 650 | ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr); |
||
| 651 | |||
| 652 | /// Determine whether this module has declared its intention to |
||
| 653 | /// directly use another module. |
||
| 654 | bool directlyUses(const Module *Requested); |
||
| 655 | |||
| 656 | /// Add the given feature requirement to the list of features |
||
| 657 | /// required by this module. |
||
| 658 | /// |
||
| 659 | /// \param Feature The feature that is required by this module (and |
||
| 660 | /// its submodules). |
||
| 661 | /// |
||
| 662 | /// \param RequiredState The required state of this feature: \c true |
||
| 663 | /// if it must be present, \c false if it must be absent. |
||
| 664 | /// |
||
| 665 | /// \param LangOpts The set of language options that will be used to |
||
| 666 | /// evaluate the availability of this feature. |
||
| 667 | /// |
||
| 668 | /// \param Target The target options that will be used to evaluate the |
||
| 669 | /// availability of this feature. |
||
| 670 | void addRequirement(StringRef Feature, bool RequiredState, |
||
| 671 | const LangOptions &LangOpts, |
||
| 672 | const TargetInfo &Target); |
||
| 673 | |||
| 674 | /// Mark this module and all of its submodules as unavailable. |
||
| 675 | void markUnavailable(bool Unimportable); |
||
| 676 | |||
| 677 | /// Find the submodule with the given name. |
||
| 678 | /// |
||
| 679 | /// \returns The submodule if found, or NULL otherwise. |
||
| 680 | Module *findSubmodule(StringRef Name) const; |
||
| 681 | Module *findOrInferSubmodule(StringRef Name); |
||
| 682 | |||
| 683 | /// Get the Global Module Fragment (sub-module) for this module, it there is |
||
| 684 | /// one. |
||
| 685 | /// |
||
| 686 | /// \returns The GMF sub-module if found, or NULL otherwise. |
||
| 687 | Module *getGlobalModuleFragment() { return findSubmodule("<global>"); } |
||
| 688 | |||
| 689 | /// Get the Private Module Fragment (sub-module) for this module, it there is |
||
| 690 | /// one. |
||
| 691 | /// |
||
| 692 | /// \returns The PMF sub-module if found, or NULL otherwise. |
||
| 693 | Module *getPrivateModuleFragment() { return findSubmodule("<private>"); } |
||
| 694 | |||
| 695 | /// Determine whether the specified module would be visible to |
||
| 696 | /// a lookup at the end of this module. |
||
| 697 | /// |
||
| 698 | /// FIXME: This may return incorrect results for (submodules of) the |
||
| 699 | /// module currently being built, if it's queried before we see all |
||
| 700 | /// of its imports. |
||
| 701 | bool isModuleVisible(const Module *M) const { |
||
| 702 | if (VisibleModulesCache.empty()) |
||
| 703 | buildVisibleModulesCache(); |
||
| 704 | return VisibleModulesCache.count(M); |
||
| 705 | } |
||
| 706 | |||
| 707 | unsigned getVisibilityID() const { return VisibilityID; } |
||
| 708 | |||
| 709 | using submodule_iterator = std::vector<Module *>::iterator; |
||
| 710 | using submodule_const_iterator = std::vector<Module *>::const_iterator; |
||
| 711 | |||
| 712 | submodule_iterator submodule_begin() { return SubModules.begin(); } |
||
| 713 | submodule_const_iterator submodule_begin() const {return SubModules.begin();} |
||
| 714 | submodule_iterator submodule_end() { return SubModules.end(); } |
||
| 715 | submodule_const_iterator submodule_end() const { return SubModules.end(); } |
||
| 716 | |||
| 717 | llvm::iterator_range<submodule_iterator> submodules() { |
||
| 718 | return llvm::make_range(submodule_begin(), submodule_end()); |
||
| 719 | } |
||
| 720 | llvm::iterator_range<submodule_const_iterator> submodules() const { |
||
| 721 | return llvm::make_range(submodule_begin(), submodule_end()); |
||
| 722 | } |
||
| 723 | |||
| 724 | /// Appends this module's list of exported modules to \p Exported. |
||
| 725 | /// |
||
| 726 | /// This provides a subset of immediately imported modules (the ones that are |
||
| 727 | /// directly exported), not the complete set of exported modules. |
||
| 728 | void getExportedModules(SmallVectorImpl<Module *> &Exported) const; |
||
| 729 | |||
| 730 | static StringRef getModuleInputBufferName() { |
||
| 731 | return "<module-includes>"; |
||
| 732 | } |
||
| 733 | |||
| 734 | /// Print the module map for this module to the given stream. |
||
| 735 | void print(raw_ostream &OS, unsigned Indent = 0, bool Dump = false) const; |
||
| 736 | |||
| 737 | /// Dump the contents of this module to the given output stream. |
||
| 738 | void dump() const; |
||
| 739 | |||
| 740 | private: |
||
| 741 | void buildVisibleModulesCache() const; |
||
| 742 | }; |
||
| 743 | |||
| 744 | /// A set of visible modules. |
||
| 745 | class VisibleModuleSet { |
||
| 746 | public: |
||
| 747 | VisibleModuleSet() = default; |
||
| 748 | VisibleModuleSet(VisibleModuleSet &&O) |
||
| 749 | : ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) { |
||
| 750 | O.ImportLocs.clear(); |
||
| 751 | ++O.Generation; |
||
| 752 | } |
||
| 753 | |||
| 754 | /// Move from another visible modules set. Guaranteed to leave the source |
||
| 755 | /// empty and bump the generation on both. |
||
| 756 | VisibleModuleSet &operator=(VisibleModuleSet &&O) { |
||
| 757 | ImportLocs = std::move(O.ImportLocs); |
||
| 758 | O.ImportLocs.clear(); |
||
| 759 | ++O.Generation; |
||
| 760 | ++Generation; |
||
| 761 | return *this; |
||
| 762 | } |
||
| 763 | |||
| 764 | /// Get the current visibility generation. Incremented each time the |
||
| 765 | /// set of visible modules changes in any way. |
||
| 766 | unsigned getGeneration() const { return Generation; } |
||
| 767 | |||
| 768 | /// Determine whether a module is visible. |
||
| 769 | bool isVisible(const Module *M) const { |
||
| 770 | return getImportLoc(M).isValid(); |
||
| 771 | } |
||
| 772 | |||
| 773 | /// Get the location at which the import of a module was triggered. |
||
| 774 | SourceLocation getImportLoc(const Module *M) const { |
||
| 775 | return M->getVisibilityID() < ImportLocs.size() |
||
| 776 | ? ImportLocs[M->getVisibilityID()] |
||
| 777 | : SourceLocation(); |
||
| 778 | } |
||
| 779 | |||
| 780 | /// A callback to call when a module is made visible (directly or |
||
| 781 | /// indirectly) by a call to \ref setVisible. |
||
| 782 | using VisibleCallback = llvm::function_ref<void(Module *M)>; |
||
| 783 | |||
| 784 | /// A callback to call when a module conflict is found. \p Path |
||
| 785 | /// consists of a sequence of modules from the conflicting module to the one |
||
| 786 | /// made visible, where each was exported by the next. |
||
| 787 | using ConflictCallback = |
||
| 788 | llvm::function_ref<void(ArrayRef<Module *> Path, Module *Conflict, |
||
| 789 | StringRef Message)>; |
||
| 790 | |||
| 791 | /// Make a specific module visible. |
||
| 792 | void setVisible(Module *M, SourceLocation Loc, |
||
| 793 | VisibleCallback Vis = [](Module *) {}, |
||
| 794 | ConflictCallback Cb = [](ArrayRef<Module *>, Module *, |
||
| 795 | StringRef) {}); |
||
| 796 | |||
| 797 | private: |
||
| 798 | /// Import locations for each visible module. Indexed by the module's |
||
| 799 | /// VisibilityID. |
||
| 800 | std::vector<SourceLocation> ImportLocs; |
||
| 801 | |||
| 802 | /// Visibility generation, bumped every time the visibility state changes. |
||
| 803 | unsigned Generation = 0; |
||
| 804 | }; |
||
| 805 | |||
| 806 | /// Abstracts clang modules and precompiled header files and holds |
||
| 807 | /// everything needed to generate debug info for an imported module |
||
| 808 | /// or PCH. |
||
| 809 | class ASTSourceDescriptor { |
||
| 810 | StringRef PCHModuleName; |
||
| 811 | StringRef Path; |
||
| 812 | StringRef ASTFile; |
||
| 813 | ASTFileSignature Signature; |
||
| 814 | Module *ClangModule = nullptr; |
||
| 815 | |||
| 816 | public: |
||
| 817 | ASTSourceDescriptor() = default; |
||
| 818 | ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, |
||
| 819 | ASTFileSignature Signature) |
||
| 820 | : PCHModuleName(std::move(Name)), Path(std::move(Path)), |
||
| 821 | ASTFile(std::move(ASTFile)), Signature(Signature) {} |
||
| 822 | ASTSourceDescriptor(Module &M); |
||
| 823 | |||
| 824 | std::string getModuleName() const; |
||
| 825 | StringRef getPath() const { return Path; } |
||
| 826 | StringRef getASTFile() const { return ASTFile; } |
||
| 827 | ASTFileSignature getSignature() const { return Signature; } |
||
| 828 | Module *getModuleOrNull() const { return ClangModule; } |
||
| 829 | }; |
||
| 830 | |||
| 831 | |||
| 832 | } // namespace clang |
||
| 833 | |||
| 834 | #endif // LLVM_CLANG_BASIC_MODULE_H |