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