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