diff options
Diffstat (limited to 'clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r-- | clang/lib/Lex/HeaderSearch.cpp | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index f0c5900c8ce45..1df28cc07209d 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -133,7 +133,7 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { void HeaderSearch::getHeaderMapFileNames( SmallVectorImpl<std::string> &Names) const { for (auto &HM : HeaderMaps) - Names.push_back(HM.first->getName()); + Names.push_back(std::string(HM.first->getName())); } std::string HeaderSearch::getCachedModuleFileName(Module *Module) { @@ -145,7 +145,7 @@ std::string HeaderSearch::getCachedModuleFileName(Module *Module) { std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName, bool FileMapOnly) { // First check the module name to pcm file map. - auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName)); + auto i(HSOpts->PrebuiltModuleFiles.find(ModuleName)); if (i != HSOpts->PrebuiltModuleFiles.end()) return i->second; @@ -159,7 +159,7 @@ std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName, llvm::sys::fs::make_absolute(Result); llvm::sys::path::append(Result, ModuleName + ".pcm"); if (getFileMgr().getFile(Result.str())) - return Result.str().str(); + return std::string(Result); } return {}; } @@ -184,7 +184,8 @@ std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName, // // To avoid false-negatives, we form as canonical a path as we can, and map // to lower-case in case we're on a case-insensitive file system. - std::string Parent = llvm::sys::path::parent_path(ModuleMapPath); + std::string Parent = + std::string(llvm::sys::path::parent_path(ModuleMapPath)); if (Parent.empty()) Parent = "."; auto Dir = FileMgr.getDirectory(Parent); @@ -468,7 +469,7 @@ getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, // If this is a framework directory, then we're a subframework of this // framework. if (llvm::sys::path::extension(DirName) == ".framework") { - SubmodulePath.push_back(llvm::sys::path::stem(DirName)); + SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName))); TopFrameworkDir = *Dir; } } while (true); @@ -1218,9 +1219,11 @@ HeaderSearch::getExistingFileInfo(const FileEntry *FE, } bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { - // Check if we've ever seen this file as a header. + // Check if we've entered this file and found an include guard or #pragma + // once. Note that we dor't check for #import, because that's not a property + // of the file itself. if (auto *HFI = getExistingFileInfo(File)) - return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro || + return HFI->isPragmaOnce || HFI->ControllingMacro || HFI->ControllingMacroID; return false; } @@ -1273,14 +1276,12 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, // // It's common that libc++ and system modules will both define such // submodules. Make sure cached results for a builtin header won't - // prevent other builtin modules to potentially enter the builtin header. - // Note that builtins are header guarded and the decision to actually - // enter them is postponed to the controlling macros logic below. + // prevent other builtin modules from potentially entering the builtin + // header. Note that builtins are header guarded and the decision to + // actually enter them is postponed to the controlling macros logic below. bool TryEnterHdr = false; if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader) - TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() && - ModuleMap::isBuiltinHeader( - llvm::sys::path::filename(File->getName())); + TryEnterHdr = ModMap.isBuiltinHeader(File); // Textual headers can be #imported from different modules. Since ObjC // headers find in the wild might rely only on #import and do not contain @@ -1398,25 +1399,46 @@ HeaderSearch::findModuleForHeader(const FileEntry *File, return ModMap.findModuleForHeader(File, AllowTextual); } +ArrayRef<ModuleMap::KnownHeader> +HeaderSearch::findAllModulesForHeader(const FileEntry *File) const { + if (ExternalSource) { + // Make sure the external source has handled header info about this file, + // which includes whether the file is part of a module. + (void)getExistingFileInfo(File); + } + return ModMap.findAllModulesForHeader(File); +} + static bool suggestModule(HeaderSearch &HS, const FileEntry *File, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) { ModuleMap::KnownHeader Module = HS.findModuleForHeader(File, /*AllowTextual*/true); - if (SuggestedModule) - *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader) - ? ModuleMap::KnownHeader() - : Module; // If this module specifies [no_undeclared_includes], we cannot find any // file that's in a non-dependency module. if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) { - HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/false); + HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false); if (!RequestingModule->directlyUses(Module.getModule())) { + // Builtin headers are a special case. Multiple modules can use the same + // builtin as a modular header (see also comment in + // ShouldEnterIncludeFile()), so the builtin header may have been + // "claimed" by an unrelated module. This shouldn't prevent us from + // including the builtin header textually in this module. + if (HS.getModuleMap().isBuiltinHeader(File)) { + if (SuggestedModule) + *SuggestedModule = ModuleMap::KnownHeader(); + return true; + } return false; } } + if (SuggestedModule) + *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader) + ? ModuleMap::KnownHeader() + : Module; + return true; } @@ -1567,6 +1589,16 @@ HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { llvm::sys::path::append(ModuleMapFileName, "module.map"); if (auto F = FileMgr.getFile(ModuleMapFileName)) return *F; + + // For frameworks, allow to have a private module map with a preferred + // spelling when a public module map is absent. + if (IsFramework) { + ModuleMapFileName = Dir->getName(); + llvm::sys::path::append(ModuleMapFileName, "Modules", + "module.private.modulemap"); + if (auto F = FileMgr.getFile(ModuleMapFileName)) + return *F; + } return nullptr; } |