From: Douglas Gregor Date: Mon, 28 Nov 2011 23:16:06 +0000 (+0000) Subject: When attempting to load a module that is not in the module cache, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a4d36a6dd00c1495cfe3b64f949d70ba9f778391;p=clang When attempting to load a module that is not in the module cache, return the module itself (in the module map) rather than returning the umbrella header used to build the module. While doing this, make sure that we're inferring modules for frameworks to build that module. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145310 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index a6d7520f29..79de453a59 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -350,19 +350,17 @@ public: /// \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; } diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 838a0675f2..d1db46c4e1 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -1045,15 +1045,14 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc, 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. @@ -1080,8 +1079,9 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc, 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) { diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 318e57dc01..c1c3a2f7bf 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -102,8 +102,10 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { } 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) @@ -116,24 +118,29 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName, 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; @@ -160,39 +167,11 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName, } } - // 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); } //===----------------------------------------------------------------------===//