|
@@ -165,8 +165,8 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
|
|
|
|
|
|
bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
|
|
|
// Search for a module map file in this directory.
|
|
|
- if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem)
|
|
|
- == LMM_NewlyLoaded) {
|
|
|
+ if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
|
|
|
+ /*IsFramework*/false) == LMM_NewlyLoaded) {
|
|
|
// We just loaded a module map file; check whether the module is
|
|
|
// available now.
|
|
|
Module = ModMap.findModule(ModuleName);
|
|
@@ -179,7 +179,8 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
|
|
|
SmallString<128> NestedModuleMapDirName;
|
|
|
NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
|
|
|
llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
|
|
|
- if (loadModuleMapFile(NestedModuleMapDirName, IsSystem) == LMM_NewlyLoaded){
|
|
|
+ if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
|
|
|
+ /*IsFramework*/false) == LMM_NewlyLoaded){
|
|
|
// If we just loaded a module map file, look for the module again.
|
|
|
Module = ModMap.findModule(ModuleName);
|
|
|
if (Module)
|
|
@@ -1097,8 +1098,8 @@ bool HeaderSearch::hasModuleMap(StringRef FileName,
|
|
|
if (!Dir)
|
|
|
return false;
|
|
|
|
|
|
- // Try to load the "module.map" file in this directory.
|
|
|
- switch (loadModuleMapFile(Dir, IsSystem)) {
|
|
|
+ // Try to load the module map file in this directory.
|
|
|
+ switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/false)) {
|
|
|
case LMM_NewlyLoaded:
|
|
|
case LMM_AlreadyLoaded:
|
|
|
// Success. All of the directories we stepped through inherit this module
|
|
@@ -1132,36 +1133,84 @@ HeaderSearch::findModuleForHeader(const FileEntry *File) const {
|
|
|
return ModMap.findModuleForHeader(File);
|
|
|
}
|
|
|
|
|
|
+static const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath,
|
|
|
+ const DirectoryEntry *Directory,
|
|
|
+ FileManager &FileMgr) {
|
|
|
+ StringRef Filename = llvm::sys::path::filename(ModuleMapPath);
|
|
|
+ SmallString<128> PrivateFilename(Directory->getName());
|
|
|
+ if (Filename == "module.map")
|
|
|
+ llvm::sys::path::append(PrivateFilename, "module_private.map");
|
|
|
+ else if (Filename == "module.modulemap")
|
|
|
+ llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
|
|
|
+ else
|
|
|
+ return nullptr;
|
|
|
+ return FileMgr.getFile(PrivateFilename);
|
|
|
+}
|
|
|
+
|
|
|
bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
|
|
|
+ switch (loadModuleMapFileImpl(File, IsSystem)) {
|
|
|
+ case LMM_AlreadyLoaded:
|
|
|
+ case LMM_NewlyLoaded:
|
|
|
+ return false;
|
|
|
+ case LMM_NoDirectory:
|
|
|
+ case LMM_InvalidModuleMap:
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+HeaderSearch::LoadModuleMapResult
|
|
|
+HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) {
|
|
|
+ assert(File && "expected FileEntry");
|
|
|
+
|
|
|
const DirectoryEntry *Dir = File->getDir();
|
|
|
-
|
|
|
- llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
|
|
|
- = DirectoryHasModuleMap.find(Dir);
|
|
|
+ auto KnownDir = DirectoryHasModuleMap.find(Dir);
|
|
|
if (KnownDir != DirectoryHasModuleMap.end())
|
|
|
- return !KnownDir->second;
|
|
|
-
|
|
|
- bool Result = ModMap.parseModuleMapFile(File, IsSystem);
|
|
|
- if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") {
|
|
|
- // If the file we loaded was a module.map, look for the corresponding
|
|
|
- // module_private.map.
|
|
|
- SmallString<128> PrivateFilename(Dir->getName());
|
|
|
- llvm::sys::path::append(PrivateFilename, "module_private.map");
|
|
|
- if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename))
|
|
|
- Result = ModMap.parseModuleMapFile(PrivateFile, IsSystem);
|
|
|
+ return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
|
|
|
+
|
|
|
+ if (ModMap.parseModuleMapFile(File, IsSystem)) {
|
|
|
+ DirectoryHasModuleMap[Dir] = false;
|
|
|
+ return LMM_InvalidModuleMap;
|
|
|
}
|
|
|
-
|
|
|
- DirectoryHasModuleMap[Dir] = !Result;
|
|
|
- return Result;
|
|
|
+
|
|
|
+ // Try to load a corresponding private module map.
|
|
|
+ if (const FileEntry *PMMFile =
|
|
|
+ getPrivateModuleMap(File->getName(), Dir, FileMgr)) {
|
|
|
+ if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) {
|
|
|
+ DirectoryHasModuleMap[Dir] = false;
|
|
|
+ return LMM_InvalidModuleMap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // This directory has a module map.
|
|
|
+ DirectoryHasModuleMap[Dir] = true;
|
|
|
+ return LMM_NewlyLoaded;
|
|
|
+}
|
|
|
+
|
|
|
+const FileEntry *
|
|
|
+HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {
|
|
|
+ // For frameworks, the preferred spelling is Modules/module.modulemap, but
|
|
|
+ // module.map at the framework root is also accepted.
|
|
|
+ SmallString<128> ModuleMapFileName(Dir->getName());
|
|
|
+ if (IsFramework)
|
|
|
+ llvm::sys::path::append(ModuleMapFileName, "Modules");
|
|
|
+ llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
|
|
|
+ if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
|
|
|
+ return F;
|
|
|
+
|
|
|
+ // Continue to allow module.map
|
|
|
+ ModuleMapFileName = Dir->getName();
|
|
|
+ llvm::sys::path::append(ModuleMapFileName, "module.map");
|
|
|
+ return FileMgr.getFile(ModuleMapFileName);
|
|
|
}
|
|
|
|
|
|
-Module *HeaderSearch::loadFrameworkModule(StringRef Name,
|
|
|
+Module *HeaderSearch::loadFrameworkModule(StringRef Name,
|
|
|
const DirectoryEntry *Dir,
|
|
|
bool IsSystem) {
|
|
|
if (Module *Module = ModMap.findModule(Name))
|
|
|
return Module;
|
|
|
|
|
|
// Try to load a module map file.
|
|
|
- switch (loadModuleMapFile(Dir, IsSystem)) {
|
|
|
+ switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
|
|
|
case LMM_InvalidModuleMap:
|
|
|
break;
|
|
|
|
|
@@ -1201,53 +1250,30 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name,
|
|
|
|
|
|
|
|
|
HeaderSearch::LoadModuleMapResult
|
|
|
-HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem) {
|
|
|
+HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
|
|
|
+ bool IsFramework) {
|
|
|
if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
|
|
|
- return loadModuleMapFile(Dir, IsSystem);
|
|
|
+ return loadModuleMapFile(Dir, IsSystem, IsFramework);
|
|
|
|
|
|
return LMM_NoDirectory;
|
|
|
}
|
|
|
|
|
|
HeaderSearch::LoadModuleMapResult
|
|
|
-HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem) {
|
|
|
- llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
|
|
|
- = DirectoryHasModuleMap.find(Dir);
|
|
|
+HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
|
|
|
+ bool IsFramework) {
|
|
|
+ auto KnownDir = DirectoryHasModuleMap.find(Dir);
|
|
|
if (KnownDir != DirectoryHasModuleMap.end())
|
|
|
return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
|
|
|
-
|
|
|
- SmallString<128> ModuleMapFileName;
|
|
|
- ModuleMapFileName += Dir->getName();
|
|
|
- unsigned ModuleMapDirNameLen = ModuleMapFileName.size();
|
|
|
- llvm::sys::path::append(ModuleMapFileName, "module.map");
|
|
|
- if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
|
|
|
- // We have found a module map file. Try to parse it.
|
|
|
- if (ModMap.parseModuleMapFile(ModuleMapFile, IsSystem)) {
|
|
|
- // No suitable module map.
|
|
|
- DirectoryHasModuleMap[Dir] = false;
|
|
|
- return LMM_InvalidModuleMap;
|
|
|
- }
|
|
|
|
|
|
- // This directory has a module map.
|
|
|
- DirectoryHasModuleMap[Dir] = true;
|
|
|
-
|
|
|
- // Check whether there is a private module map that we need to load as well.
|
|
|
- ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen,
|
|
|
- ModuleMapFileName.end());
|
|
|
- llvm::sys::path::append(ModuleMapFileName, "module_private.map");
|
|
|
- if (const FileEntry *PrivateModuleMapFile
|
|
|
- = FileMgr.getFile(ModuleMapFileName)) {
|
|
|
- if (ModMap.parseModuleMapFile(PrivateModuleMapFile, IsSystem)) {
|
|
|
- // No suitable module map.
|
|
|
- DirectoryHasModuleMap[Dir] = false;
|
|
|
- return LMM_InvalidModuleMap;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return LMM_NewlyLoaded;
|
|
|
+ if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
|
|
|
+ LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem);
|
|
|
+ // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
|
|
|
+ // E.g. Foo.framework/Modules/module.modulemap
|
|
|
+ // ^Dir ^ModuleMapFile
|
|
|
+ if (Result == LMM_NewlyLoaded)
|
|
|
+ DirectoryHasModuleMap[Dir] = true;
|
|
|
+ return Result;
|
|
|
}
|
|
|
-
|
|
|
- // No suitable module map.
|
|
|
- DirectoryHasModuleMap[Dir] = false;
|
|
|
return LMM_InvalidModuleMap;
|
|
|
}
|
|
|
|
|
@@ -1285,7 +1311,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
|
|
|
continue;
|
|
|
|
|
|
// Try to load a module map file for the search directory.
|
|
|
- loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem);
|
|
|
+ loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false);
|
|
|
|
|
|
// Try to load module map files for immediate subdirectories of this search
|
|
|
// directory.
|
|
@@ -1310,7 +1336,8 @@ void HeaderSearch::loadTopLevelSystemModules() {
|
|
|
|
|
|
// Try to load a module map file for the search directory.
|
|
|
loadModuleMapFile(SearchDirs[Idx].getDir(),
|
|
|
- SearchDirs[Idx].isSystemHeaderDirectory());
|
|
|
+ SearchDirs[Idx].isSystemHeaderDirectory(),
|
|
|
+ SearchDirs[Idx].isFramework());
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1323,7 +1350,8 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
|
|
|
llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
|
|
|
for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
|
|
|
Dir != DirEnd && !EC; Dir.increment(EC)) {
|
|
|
- loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory());
|
|
|
+ loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
|
|
|
+ SearchDir.isFramework());
|
|
|
}
|
|
|
|
|
|
SearchDir.setSearchedAllModuleMaps(true);
|