ModuleLoader.h revision 360784
1204431Sraj//===- ModuleLoader.h - Module Loader Interface -----------------*- C++ -*-===// 2204431Sraj// 3204431Sraj// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4204431Sraj// See https://llvm.org/LICENSE.txt for license information. 5204431Sraj// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6204431Sraj// 7204431Sraj//===----------------------------------------------------------------------===// 8204431Sraj// 9204431Sraj// This file defines the ModuleLoader interface, which is responsible for 10204431Sraj// loading named modules. 11204431Sraj// 12204431Sraj//===----------------------------------------------------------------------===// 13204431Sraj 14204431Sraj#ifndef LLVM_CLANG_LEX_MODULELOADER_H 15204431Sraj#define LLVM_CLANG_LEX_MODULELOADER_H 16204431Sraj 17204431Sraj#include "clang/Basic/LLVM.h" 18204431Sraj#include "clang/Basic/Module.h" 19204431Sraj#include "clang/Basic/SourceLocation.h" 20204431Sraj#include "llvm/ADT/ArrayRef.h" 21204431Sraj#include "llvm/ADT/PointerIntPair.h" 22204431Sraj#include "llvm/ADT/StringRef.h" 23204431Sraj#include <utility> 24204431Sraj 25204431Srajnamespace clang { 26204431Sraj 27204431Srajclass GlobalModuleIndex; 28204431Srajclass IdentifierInfo; 29204431Sraj 30204431Sraj/// A sequence of identifier/location pairs used to describe a particular 31204431Sraj/// module or submodule, e.g., std.vector. 32204431Srajusing ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>; 33204431Sraj 34204431Sraj/// Describes the result of attempting to load a module. 35204431Srajclass ModuleLoadResult { 36204431Srajpublic: 37204431Sraj enum LoadResultKind { 38204431Sraj // We either succeeded or failed to load the named module. 39204431Sraj Normal, 40204431Sraj 41204431Sraj // The module exists, but does not actually contain the named submodule. 42204431Sraj // This should only happen if the named submodule was inferred from an 43204431Sraj // umbrella directory, but not actually part of the umbrella header. 44204431Sraj MissingExpected, 45204431Sraj 46204431Sraj // The module exists but cannot be imported due to a configuration mismatch. 47204431Sraj ConfigMismatch, 48204431Sraj 49204431Sraj // We failed to load the module, but we shouldn't cache the failure. 50204431Sraj OtherUncachedFailure, 51204431Sraj }; 52204431Sraj llvm::PointerIntPair<Module *, 2, LoadResultKind> Storage; 53204431Sraj 54204431Sraj ModuleLoadResult() = default; 55204431Sraj ModuleLoadResult(Module *M) : Storage(M, Normal) {} 56204431Sraj ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {} 57204431Sraj 58204431Sraj operator Module *() const { return Storage.getPointer(); } 59204431Sraj 60204431Sraj /// Determines whether this is a normal return, whether or not loading the 61204431Sraj /// module was successful. 62204431Sraj bool isNormal() const { return Storage.getInt() == Normal; } 63204431Sraj 64204431Sraj /// Determines whether the module, which failed to load, was 65204431Sraj /// actually a submodule that we expected to see (based on implying the 66204431Sraj /// submodule from header structure), but didn't materialize in the actual 67204431Sraj /// module. 68204431Sraj bool isMissingExpected() const { return Storage.getInt() == MissingExpected; } 69204431Sraj 70204431Sraj /// Determines whether the module failed to load due to a configuration 71204431Sraj /// mismatch with an explicitly-named .pcm file from the command line. 72204431Sraj bool isConfigMismatch() const { return Storage.getInt() == ConfigMismatch; } 73204431Sraj}; 74204431Sraj 75204431Sraj/// Abstract interface for a module loader. 76204431Sraj/// 77204431Sraj/// This abstract interface describes a module loader, which is responsible 78204431Sraj/// for resolving a module name (e.g., "std") to an actual module file, and 79204431Sraj/// then loading that module. 80204431Srajclass ModuleLoader { 81204431Sraj // Building a module if true. 82204431Sraj bool BuildingModule; 83204431Sraj 84204431Srajpublic: 85204431Sraj explicit ModuleLoader(bool BuildingModule = false) 86204431Sraj : BuildingModule(BuildingModule) {} 87204431Sraj 88204431Sraj virtual ~ModuleLoader(); 89204431Sraj 90204431Sraj /// Returns true if this instance is building a module. 91204431Sraj bool buildingModule() const { 92204431Sraj return BuildingModule; 93204431Sraj } 94204431Sraj 95204431Sraj /// Flag indicating whether this instance is building a module. 96204431Sraj void setBuildingModule(bool BuildingModuleFlag) { 97204433Sraj BuildingModule = BuildingModuleFlag; 98204431Sraj } 99204433Sraj 100204431Sraj /// Attempt to load the given module. 101204433Sraj /// 102204433Sraj /// This routine attempts to load the module described by the given 103204431Sraj /// parameters. If there is a module cache, this may implicitly compile the 104204433Sraj /// module before loading it. 105204431Sraj /// 106204431Sraj /// \param ImportLoc The location of the 'import' keyword. 107204431Sraj /// 108204431Sraj /// \param Path The identifiers (and their locations) of the module 109204431Sraj /// "path", e.g., "std.vector" would be split into "std" and "vector". 110204431Sraj /// 111204431Sraj /// \param Visibility The visibility provided for the names in the loaded 112204431Sraj /// module. 113204431Sraj /// 114204431Sraj /// \param IsInclusionDirective Indicates that this module is being loaded 115204431Sraj /// implicitly, due to the presence of an inclusion directive. Otherwise, 116204431Sraj /// it is being loaded due to an import declaration. 117204431Sraj /// 118204431Sraj /// \returns If successful, returns the loaded module. Otherwise, returns 119 /// NULL to indicate that the module could not be loaded. 120 virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, 121 ModuleIdPath Path, 122 Module::NameVisibilityKind Visibility, 123 bool IsInclusionDirective) = 0; 124 125 /// Attempt to create the given module from the specified source buffer. 126 /// Does not load the module or make any submodule visible; for that, use 127 /// loadModule and makeModuleVisible. 128 /// 129 /// \param Loc The location at which to create the module. 130 /// \param ModuleName The name of the module to create. 131 /// \param Source The source of the module: a (preprocessed) module map. 132 virtual void createModuleFromSource(SourceLocation Loc, StringRef ModuleName, 133 StringRef Source) = 0; 134 135 /// Make the given module visible. 136 virtual void makeModuleVisible(Module *Mod, 137 Module::NameVisibilityKind Visibility, 138 SourceLocation ImportLoc) = 0; 139 140 /// Load, create, or return global module. 141 /// This function returns an existing global module index, if one 142 /// had already been loaded or created, or loads one if it 143 /// exists, or creates one if it doesn't exist. 144 /// Also, importantly, if the index doesn't cover all the modules 145 /// in the module map, it will be update to do so here, because 146 /// of its use in searching for needed module imports and 147 /// associated fixit messages. 148 /// \param TriggerLoc The location for what triggered the load. 149 /// \returns Returns null if load failed. 150 virtual GlobalModuleIndex *loadGlobalModuleIndex( 151 SourceLocation TriggerLoc) = 0; 152 153 /// Check global module index for missing imports. 154 /// \param Name The symbol name to look for. 155 /// \param TriggerLoc The location for what triggered the load. 156 /// \returns Returns true if any modules with that symbol found. 157 virtual bool lookupMissingImports(StringRef Name, 158 SourceLocation TriggerLoc) = 0; 159 160 bool HadFatalFailure = false; 161}; 162 163/// A module loader that doesn't know how to create or load modules. 164class TrivialModuleLoader : public ModuleLoader { 165public: 166 ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, 167 Module::NameVisibilityKind Visibility, 168 bool IsInclusionDirective) override { 169 return {}; 170 } 171 172 void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName, 173 StringRef Source) override {} 174 175 void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, 176 SourceLocation ImportLoc) override {} 177 178 GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { 179 return nullptr; 180 } 181 182 bool lookupMissingImports(StringRef Name, 183 SourceLocation TriggerLoc) override { 184 return false; 185 } 186}; 187 188} // namespace clang 189 190#endif // LLVM_CLANG_LEX_MODULELOADER_H 191