Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:57

0001 //===- ModuleLoader.h - Module Loader Interface -----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the ModuleLoader interface, which is responsible for
0010 //  loading named modules.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_LEX_MODULELOADER_H
0015 #define LLVM_CLANG_LEX_MODULELOADER_H
0016 
0017 #include "clang/Basic/LLVM.h"
0018 #include "clang/Basic/Module.h"
0019 #include "clang/Basic/SourceLocation.h"
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/PointerIntPair.h"
0022 #include "llvm/ADT/StringRef.h"
0023 #include <utility>
0024 
0025 namespace clang {
0026 
0027 class GlobalModuleIndex;
0028 class IdentifierInfo;
0029 
0030 /// A sequence of identifier/location pairs used to describe a particular
0031 /// module or submodule, e.g., std.vector.
0032 using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
0033 
0034 /// Describes the result of attempting to load a module.
0035 class ModuleLoadResult {
0036 public:
0037   enum LoadResultKind {
0038     // We either succeeded or failed to load the named module.
0039     Normal,
0040 
0041     // The module exists, but does not actually contain the named submodule.
0042     // This should only happen if the named submodule was inferred from an
0043     // umbrella directory, but not actually part of the umbrella header.
0044     MissingExpected,
0045 
0046     // The module exists but cannot be imported due to a configuration mismatch.
0047     ConfigMismatch,
0048   };
0049   llvm::PointerIntPair<Module *, 2, LoadResultKind> Storage;
0050 
0051   ModuleLoadResult() = default;
0052   ModuleLoadResult(Module *M) : Storage(M, Normal) {}
0053   ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {}
0054   ModuleLoadResult(Module *M, LoadResultKind Kind) : Storage(M, Kind) {}
0055 
0056   operator bool() const {
0057     return Storage.getInt() == Normal && Storage.getPointer();
0058   }
0059 
0060   operator Module *() const { return Storage.getPointer(); }
0061 
0062   /// Determines whether this is a normal return, whether or not loading the
0063   /// module was successful.
0064   bool isNormal() const { return Storage.getInt() == Normal; }
0065 
0066   /// Determines whether the module, which failed to load, was
0067   /// actually a submodule that we expected to see (based on implying the
0068   /// submodule from header structure), but didn't materialize in the actual
0069   /// module.
0070   bool isMissingExpected() const { return Storage.getInt() == MissingExpected; }
0071 
0072   /// Determines whether the module failed to load due to a configuration
0073   /// mismatch with an explicitly-named .pcm file from the command line.
0074   bool isConfigMismatch() const { return Storage.getInt() == ConfigMismatch; }
0075 };
0076 
0077 /// Abstract interface for a module loader.
0078 ///
0079 /// This abstract interface describes a module loader, which is responsible
0080 /// for resolving a module name (e.g., "std") to an actual module file, and
0081 /// then loading that module.
0082 class ModuleLoader {
0083   // Building a module if true.
0084   bool BuildingModule;
0085 
0086 public:
0087   explicit ModuleLoader(bool BuildingModule = false)
0088       : BuildingModule(BuildingModule) {}
0089 
0090   virtual ~ModuleLoader();
0091 
0092   /// Returns true if this instance is building a module.
0093   bool buildingModule() const {
0094     return BuildingModule;
0095   }
0096 
0097   /// Flag indicating whether this instance is building a module.
0098   void setBuildingModule(bool BuildingModuleFlag) {
0099     BuildingModule = BuildingModuleFlag;
0100   }
0101 
0102   /// Attempt to load the given module.
0103   ///
0104   /// This routine attempts to load the module described by the given
0105   /// parameters.  If there is a module cache, this may implicitly compile the
0106   /// module before loading it.
0107   ///
0108   /// \param ImportLoc The location of the 'import' keyword.
0109   ///
0110   /// \param Path The identifiers (and their locations) of the module
0111   /// "path", e.g., "std.vector" would be split into "std" and "vector".
0112   ///
0113   /// \param Visibility The visibility provided for the names in the loaded
0114   /// module.
0115   ///
0116   /// \param IsInclusionDirective Indicates that this module is being loaded
0117   /// implicitly, due to the presence of an inclusion directive. Otherwise,
0118   /// it is being loaded due to an import declaration.
0119   ///
0120   /// \returns If successful, returns the loaded module. Otherwise, returns
0121   /// NULL to indicate that the module could not be loaded.
0122   virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
0123                                       ModuleIdPath Path,
0124                                       Module::NameVisibilityKind Visibility,
0125                                       bool IsInclusionDirective) = 0;
0126 
0127   /// Attempt to create the given module from the specified source buffer.
0128   /// Does not load the module or make any submodule visible; for that, use
0129   /// loadModule and makeModuleVisible.
0130   ///
0131   /// \param Loc The location at which to create the module.
0132   /// \param ModuleName The name of the module to create.
0133   /// \param Source The source of the module: a (preprocessed) module map.
0134   virtual void createModuleFromSource(SourceLocation Loc, StringRef ModuleName,
0135                                       StringRef Source) = 0;
0136 
0137   /// Make the given module visible.
0138   virtual void makeModuleVisible(Module *Mod,
0139                                  Module::NameVisibilityKind Visibility,
0140                                  SourceLocation ImportLoc) = 0;
0141 
0142   /// Load, create, or return global module.
0143   /// This function returns an existing global module index, if one
0144   /// had already been loaded or created, or loads one if it
0145   /// exists, or creates one if it doesn't exist.
0146   /// Also, importantly, if the index doesn't cover all the modules
0147   /// in the module map, it will be update to do so here, because
0148   /// of its use in searching for needed module imports and
0149   /// associated fixit messages.
0150   /// \param TriggerLoc The location for what triggered the load.
0151   /// \returns Returns null if load failed.
0152   virtual GlobalModuleIndex *loadGlobalModuleIndex(
0153                                                 SourceLocation TriggerLoc) = 0;
0154 
0155   /// Check global module index for missing imports.
0156   /// \param Name The symbol name to look for.
0157   /// \param TriggerLoc The location for what triggered the load.
0158   /// \returns Returns true if any modules with that symbol found.
0159   virtual bool lookupMissingImports(StringRef Name,
0160                                     SourceLocation TriggerLoc) = 0;
0161 
0162   bool HadFatalFailure = false;
0163 };
0164 
0165 /// A module loader that doesn't know how to create or load modules.
0166 class TrivialModuleLoader : public ModuleLoader {
0167 public:
0168   ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
0169                               Module::NameVisibilityKind Visibility,
0170                               bool IsInclusionDirective) override {
0171     return {};
0172   }
0173 
0174   void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
0175                               StringRef Source) override {}
0176 
0177   void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
0178                          SourceLocation ImportLoc) override {}
0179 
0180   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override {
0181     return nullptr;
0182   }
0183 
0184   bool lookupMissingImports(StringRef Name,
0185                             SourceLocation TriggerLoc) override {
0186     return false;
0187   }
0188 };
0189 
0190 } // namespace clang
0191 
0192 #endif // LLVM_CLANG_LEX_MODULELOADER_H