/// \brief Search in the module cache path for a module with the given
/// name.
///
+ /// \param Module The module that was found with the given name, which
+ /// describes the module and how to build it.
+ ///
/// \param If non-NULL, will be set to the module file name we expected to
/// find (regardless of whether it was actually found or not).
///
- /// \param UmbrellaHeader If non-NULL, and no module was found in the module
- /// cache, this routine will search in the framework paths to determine
- /// whether a module can be built from an umbrella header. If so, the pointee
- /// will be set to the path of the umbrella header.
- ///
- /// \returns A file describing the named module, if available, or NULL to
- /// indicate that the module could not be found.
+ /// \returns A file describing the named module, if already available in the
+ /// cases, or NULL to indicate that the module could not be found.
const FileEntry *lookupModule(StringRef ModuleName,
- std::string *ModuleFileName = 0,
- std::string *UmbrellaHeader = 0);
+ ModuleMap::Module *&Module,
+ std::string *ModuleFileName = 0);
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
CurFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
// Search for a module with the given name.
- std::string UmbrellaHeader;
+ ModuleMap::Module *Module = 0;
std::string ModuleFileName;
const FileEntry *ModuleFile
- = PP->getHeaderSearchInfo().lookupModule(ModuleName.getName(),
- &ModuleFileName,
- &UmbrellaHeader);
+ = PP->getHeaderSearchInfo().lookupModule(ModuleName.getName(), Module,
+ &ModuleFileName);
bool BuildingModule = false;
- if (!ModuleFile && !UmbrellaHeader.empty()) {
+ if (!ModuleFile && Module && Module->UmbrellaHeader) {
// We didn't find the module, but there is an umbrella header that
// can be used to create the module file. Create a separate compilation
// module to do so.
getDiagnostics().Report(ModuleNameLoc, diag::warn_module_build)
<< ModuleName.getName();
BuildingModule = true;
- compileModule(*this, ModuleName.getName(), ModuleFileName, UmbrellaHeader);
- ModuleFile = PP->getHeaderSearchInfo().lookupModule(ModuleName.getName());
+ compileModule(*this, ModuleName.getName(), ModuleFileName,
+ Module->UmbrellaHeader->getName());
+ ModuleFile = FileMgr->getFile(ModuleFileName);
}
if (!ModuleFile) {
}
const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
- std::string *ModuleFileName,
- std::string *UmbrellaHeader) {
+ ModuleMap::Module *&Module,
+ std::string *ModuleFileName) {
+ Module = 0;
+
// If we don't have a module cache path, we can't do anything.
if (ModuleCachePath.empty()) {
if (ModuleFileName)
llvm::sys::path::append(FileName, ModuleName + ".pcm");
if (ModuleFileName)
*ModuleFileName = FileName.str();
-
- if (const FileEntry *ModuleFile
- = getFileMgr().getFile(FileName, /*OpenFile=*/false,
- /*CacheFailure=*/false))
- return ModuleFile;
-
- // We didn't find the module. If we're not supposed to look for an
- // umbrella header, this is the end of the road.
- if (!UmbrellaHeader)
- return 0;
-
+
// Look in the module map to determine if there is a module by this name.
- ModuleMap::Module *Module = ModMap.findModule(ModuleName);
+ Module = ModMap.findModule(ModuleName);
if (!Module) {
// Look through the various header search paths to load any avaiable module
// maps, searching for a module map that describes this module.
for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
- // Skip non-normal include paths
+ if (SearchDirs[Idx].isFramework()) {
+ // Search for or infer a module map for a framework.
+ llvm::SmallString<128> FrameworkDirName;
+ FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
+ llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework");
+ if (const DirectoryEntry *FrameworkDir
+ = FileMgr.getDirectory(FrameworkDirName)) {
+ Module = getFrameworkModule(ModuleName, FrameworkDir);
+ if (Module)
+ break;
+ }
+ }
+
+ // FIXME: Figure out how header maps and module maps will work together.
+
+ // Only deal with normal search directories.
if (!SearchDirs[Idx].isNormalDir())
continue;
}
}
- // If we have a module with an umbrella header
- // FIXME: Even if it doesn't have an umbrella header, we should be able to
- // handle the module. However, the caller isn't ready for that yet.
- if (Module && Module->UmbrellaHeader) {
- *UmbrellaHeader = Module->UmbrellaHeader->getName();
- return 0;
- }
-
- // Look in each of the framework directories for an umbrella header with
- // the same name as the module.
- llvm::SmallString<128> UmbrellaHeaderName;
- UmbrellaHeaderName = ModuleName;
- UmbrellaHeaderName += '/';
- UmbrellaHeaderName += ModuleName;
- UmbrellaHeaderName += ".h";
- for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
- // Skip non-framework include paths
- if (!SearchDirs[Idx].isFramework())
- continue;
-
- // Look for the umbrella header in this directory.
- if (const FileEntry *HeaderFile
- = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0,
- StringRef(), 0)) {
- *UmbrellaHeader = HeaderFile->getName();
- return 0;
- }
- }
-
- // We did not find an umbrella header. Clear out the UmbrellaHeader pointee
- // so our caller knows that we failed.
- UmbrellaHeader->clear();
- return 0;
+ // Look for the module file in the module cache.
+ // FIXME: If we didn't find a description of the module itself, should we
+ // even try to find the module in the cache?
+ return getFileMgr().getFile(FileName, /*OpenFile=*/false,
+ /*CacheFailure=*/false);
}
//===----------------------------------------------------------------------===//