16aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===//
26aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//
36aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//                     The LLVM Compiler Infrastructure
46aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//
56aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor// This file is distributed under the University of Illinois Open Source
66aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor// License. See LICENSE.TXT for details.
76aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//
86aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//===----------------------------------------------------------------------===//
96aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//
106aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//  This file defines the ModuleLoader interface, which is responsible for
116aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//  loading named modules.
126aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//
136aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor//===----------------------------------------------------------------------===//
146aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H
156aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor#define LLVM_CLANG_LEX_MODULE_LOADER_H
166aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor
175e35693721364673f8196e4f5a370f56b92e6053Douglas Gregor#include "clang/Basic/Module.h"
186aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor#include "clang/Basic/SourceLocation.h"
193d3589db579f7695667b913c5043dd264ebe546fDouglas Gregor#include "llvm/ADT/ArrayRef.h"
20463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor#include "llvm/ADT/PointerIntPair.h"
216aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor
226aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregornamespace clang {
236aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass GlobalModuleIndex;
256aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregorclass IdentifierInfo;
26463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregorclass Module;
27463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
283d3589db579f7695667b913c5043dd264ebe546fDouglas Gregor/// \brief A sequence of identifier/location pairs used to describe a particular
293d3589db579f7695667b913c5043dd264ebe546fDouglas Gregor/// module or submodule, e.g., std.vector.
30cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkotypedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
31463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
32463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor/// \brief Describes the result of attempting to load a module.
33463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregorclass ModuleLoadResult {
34463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  llvm::PointerIntPair<Module *, 1, bool> Storage;
35463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
36463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregorpublic:
37463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  ModuleLoadResult() : Storage() { }
38463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
39463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  ModuleLoadResult(Module *module, bool missingExpected)
40463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor    : Storage(module, missingExpected) { }
41463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
42463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  operator Module *() const { return Storage.getPointer(); }
43463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
44463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  /// \brief Determines whether the module, which failed to load, was
45463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  /// actually a submodule that we expected to see (based on implying the
46463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  /// submodule from header structure), but didn't materialize in the actual
47463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  /// module.
48463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  bool isMissingExpected() const { return Storage.getInt(); }
49463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor};
50463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor
516aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor/// \brief Abstract interface for a module loader.
526aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor///
536aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor/// This abstract interface describes a module loader, which is responsible
546aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor/// for resolving a module name (e.g., "std") to an actual module file, and
556aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor/// then loading that module.
566aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregorclass ModuleLoader {
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Building a module if true.
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool BuildingModule;
596aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregorpublic:
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  explicit ModuleLoader(bool BuildingModule = false) :
616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    BuildingModule(BuildingModule),
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    HadFatalFailure(false) {}
633b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis
646aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  virtual ~ModuleLoader();
656aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Returns true if this instance is building a module.
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool buildingModule() const {
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return BuildingModule;
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Flag indicating whether this instance is building a module.
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setBuildingModule(bool BuildingModuleFlag) {
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    BuildingModule = BuildingModuleFlag;
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
756aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  /// \brief Attempt to load the given module.
766aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  ///
776aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  /// This routine attempts to load the module described by the given
786aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  /// parameters.
796aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  ///
806aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  /// \param ImportLoc The location of the 'import' keyword.
815e35693721364673f8196e4f5a370f56b92e6053Douglas Gregor  ///
823d3589db579f7695667b913c5043dd264ebe546fDouglas Gregor  /// \param Path The identifiers (and their locations) of the module
833d3589db579f7695667b913c5043dd264ebe546fDouglas Gregor  /// "path", e.g., "std.vector" would be split into "std" and "vector".
845e35693721364673f8196e4f5a370f56b92e6053Douglas Gregor  ///
855e35693721364673f8196e4f5a370f56b92e6053Douglas Gregor  /// \param Visibility The visibility provided for the names in the loaded
865e35693721364673f8196e4f5a370f56b92e6053Douglas Gregor  /// module.
876aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor  ///
8893ebfa6139bbca4d446c7343e3afc8e5ec777484Douglas Gregor  /// \param IsInclusionDirective Indicates that this module is being loaded
8993ebfa6139bbca4d446c7343e3afc8e5ec777484Douglas Gregor  /// implicitly, due to the presence of an inclusion directive. Otherwise,
9093ebfa6139bbca4d446c7343e3afc8e5ec777484Douglas Gregor  /// it is being loaded due to an import declaration.
9193ebfa6139bbca4d446c7343e3afc8e5ec777484Douglas Gregor  ///
921a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  /// \returns If successful, returns the loaded module. Otherwise, returns
931a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  /// NULL to indicate that the module could not be loaded.
94463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
95463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor                                      ModuleIdPath Path,
96463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor                                      Module::NameVisibilityKind Visibility,
97463d90986ec54c62bf8fe31193ef5db701db48a5Douglas Gregor                                      bool IsInclusionDirective) = 0;
98ca2ab45341c448284cf93770018c717810575f86Douglas Gregor
99ca2ab45341c448284cf93770018c717810575f86Douglas Gregor  /// \brief Make the given module visible.
100ca2ab45341c448284cf93770018c717810575f86Douglas Gregor  virtual void makeModuleVisible(Module *Mod,
1015ebcb20b0331a6e64c213f0bb5f4bed9a9e8eb34Argyrios Kyrtzidis                                 Module::NameVisibilityKind Visibility,
102906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor                                 SourceLocation ImportLoc,
103906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor                                 bool Complain) = 0;
1043b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Load, create, or return global module.
1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// This function returns an existing global module index, if one
1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// had already been loaded or created, or loads one if it
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// exists, or creates one if it doesn't exist.
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// Also, importantly, if the index doesn't cover all the modules
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// in the module map, it will be update to do so here, because
1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// of its use in searching for needed module imports and
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// associated fixit messages.
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param TriggerLoc The location for what triggered the load.
1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \returns Returns null if load failed.
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual GlobalModuleIndex *loadGlobalModuleIndex(
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                                SourceLocation TriggerLoc) = 0;
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// Check global module index for missing imports.
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param Name The symbol name to look for.
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param TriggerLoc The location for what triggered the load.
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \returns Returns true if any modules with that symbol found.
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual bool lookupMissingImports(StringRef Name,
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                    SourceLocation TriggerLoc) = 0;
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1253b7deda7137e62810a810ce25b062927a9fc7c71Argyrios Kyrtzidis  bool HadFatalFailure;
1266aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor};
1276aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor
1286aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor}
1296aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor
1306aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor#endif
131