diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp | 104 |
1 files changed, 65 insertions, 39 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp index d6b255f..983dc18 100644 --- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp @@ -14,10 +14,13 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/HeaderMap.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallString.h" @@ -32,9 +35,13 @@ using namespace clang; const IdentifierInfo * -HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { - if (ControllingMacro) +HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) { + if (ControllingMacro) { + if (ControllingMacro->isOutOfDate()) + External->updateOutOfDateIdentifier( + *const_cast<IdentifierInfo *>(ControllingMacro)); return ControllingMacro; + } if (!ControllingMacroID || !External) return nullptr; @@ -145,11 +152,12 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, auto FileName = llvm::sys::path::filename(ModuleMapPath); llvm::hash_code Hash = - llvm::hash_combine(DirName.lower(), FileName.lower()); + llvm::hash_combine(DirName.lower(), FileName.lower(), + HSOpts->ModuleFormat); SmallString<128> HashStr; llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36); - llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm"); + llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm"); } return Result.str().str(); } @@ -157,7 +165,7 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { // Look in the module map to determine if there is a module by this name. Module *Module = ModMap.findModule(ModuleName); - if (Module || !AllowSearch || !LangOpts.ModulesImplicitMaps) + if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps) return Module; // Look through the various header search paths to load any available module @@ -297,7 +305,7 @@ const FileEntry *DirectoryLookup::LookupFile( RelativePath->append(Filename.begin(), Filename.end()); } - return getFileAndSuggestModule(HS, TmpDir.str(), getDir(), + return getFileAndSuggestModule(HS, TmpDir, getDir(), isSystemHeaderDirectory(), SuggestedModule); } @@ -438,7 +446,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( HS.IncrementFrameworkLookupCount(); // If the framework dir doesn't exist, we fail. - const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); + const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName); if (!Dir) return nullptr; // Otherwise, if it does, remember that this is the right direntry for this @@ -450,7 +458,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( if (getDirCharacteristic() == SrcMgr::C_User) { SmallString<1024> SystemFrameworkMarker(FrameworkName); SystemFrameworkMarker += ".system_framework"; - if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) { + if (llvm::sys::fs::exists(SystemFrameworkMarker)) { CacheEntry.IsUserSpecifiedSystemFramework = true; } } @@ -476,7 +484,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( } FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); - const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), + const FileEntry *FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule); if (!FE) { // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" @@ -487,7 +495,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( SearchPath->insert(SearchPath->begin()+OrigSize, Private, Private+strlen(Private)); - FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule); + FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule); } // If we found the header and are allowed to suggest a module, do so now. @@ -526,9 +534,13 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( // Load this framework module. If that succeeds, find the suggested module // for this header, if any. bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; - if (HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { - *SuggestedModule = HS.findModuleForHeader(FE); - } + HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem); + + // FIXME: This can find a module not part of ModuleName, which is + // important so that we're consistent about whether this header + // corresponds to a module. Possibly we should lock down framework modules + // so that this is not possible. + *SuggestedModule = HS.findModuleForHeader(FE); } else { *SuggestedModule = HS.findModuleForHeader(FE); } @@ -594,7 +606,13 @@ const FileEntry *HeaderSearch::LookupFile( RelativePath->append(Filename.begin(), Filename.end()); } // Otherwise, just return the file. - return FileMgr.getFile(Filename, /*openFile=*/true); + const FileEntry *File = FileMgr.getFile(Filename, /*openFile=*/true); + if (File && SuggestedModule) { + // If there is a module that corresponds to this header, suggest it. + hasModuleMap(Filename, File->getDir(), /*SystemHeaderDir*/false); + *SuggestedModule = findModuleForHeader(File); + } + return File; } // This is the header that MSVC's header search would have found. @@ -628,7 +646,7 @@ const FileEntry *HeaderSearch::LookupFile( bool IncluderIsSystemHeader = Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User; if (const FileEntry *FE = getFileAndSuggestModule( - *this, TmpDir.str(), IncluderAndDir.second, + *this, TmpDir, IncluderAndDir.second, IncluderIsSystemHeader, SuggestedModule)) { if (!Includer) { assert(First && "only first includer can have no file"); @@ -865,7 +883,7 @@ LookupSubframeworkHeader(StringRef Filename, ++NumSubFrameworkLookups; // If the framework dir doesn't exist, we fail. - const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); + const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName); if (!Dir) return nullptr; // Otherwise, if it does, remember that this is the right direntry for this @@ -890,7 +908,7 @@ LookupSubframeworkHeader(StringRef Filename, } HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); - if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { + if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) { // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" HeadersFilename = FrameworkName; @@ -902,7 +920,7 @@ LookupSubframeworkHeader(StringRef Filename, } HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); - if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) + if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) return nullptr; } @@ -979,7 +997,8 @@ HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { return HFI; } -bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const { +bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, + HeaderFileInfo &Result) const { if (FE->getUID() >= FileInfo.size()) return false; const HeaderFileInfo &HFI = FileInfo[FE->getUID()]; @@ -1012,11 +1031,13 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, HeaderFileInfo &HFI = FileInfo[FE->getUID()]; HFI.isModuleHeader = true; - HFI.isCompilingModuleHeader = isCompilingModuleHeader; + HFI.isCompilingModuleHeader |= isCompilingModuleHeader; HFI.setHeaderRole(Role); } -bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ +bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, + const FileEntry *File, + bool isImport, Module *M) { ++NumIncluded; // Count # of attempted #includes. // Get information about this file. @@ -1040,11 +1061,16 @@ bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ // Next, check to see if the file is wrapped with #ifndef guards. If so, and // if the macro that guards it is defined, we know the #include has no effect. if (const IdentifierInfo *ControllingMacro - = FileInfo.getControllingMacro(ExternalLookup)) - if (ControllingMacro->hasMacroDefinition()) { + = FileInfo.getControllingMacro(ExternalLookup)) { + // If the header corresponds to a module, check whether the macro is already + // defined in that module rather than checking in the current set of visible + // modules. + if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M) + : PP.isMacroDefined(ControllingMacro)) { ++NumMultiIncludeFileOptzn; return false; } + } // Increment the number of times this file has been included. ++FileInfo.NumIncludes; @@ -1067,7 +1093,7 @@ StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { bool HeaderSearch::hasModuleMap(StringRef FileName, const DirectoryEntry *Root, bool IsSystem) { - if (!enabledModules() || !LangOpts.ModulesImplicitMaps) + if (!HSOpts->ImplicitModuleMaps) return false; SmallVector<const DirectoryEntry *, 2> FixUpDirectories; @@ -1194,7 +1220,7 @@ HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, const FileEntry * HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { - if (!LangOpts.ModulesImplicitMaps) + if (!HSOpts->ImplicitModuleMaps) return nullptr; // For frameworks, the preferred spelling is Modules/module.modulemap, but // module.map at the framework root is also accepted. @@ -1220,6 +1246,9 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, // Try to load a module map file. switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { case LMM_InvalidModuleMap: + // Try to infer a module map from the framework directory. + if (HSOpts->ImplicitModuleMaps) + ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr); break; case LMM_AlreadyLoaded: @@ -1227,15 +1256,10 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, return nullptr; case LMM_NewlyLoaded: - return ModMap.findModule(Name); + break; } - - // Try to infer a module map from the framework directory. - if (LangOpts.ModulesImplicitMaps) - return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr); - - return nullptr; + return ModMap.findModule(Name); } @@ -1273,7 +1297,7 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { Modules.clear(); - if (LangOpts.ModulesImplicitMaps) { + if (HSOpts->ImplicitModuleMaps) { // Load module maps for each of the header search directories. for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); @@ -1284,7 +1308,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { DirNative); // Search each of the ".framework" directories to load them as modules. - for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; + for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { if (llvm::sys::path::extension(Dir->path()) != ".framework") continue; @@ -1324,7 +1348,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { } void HeaderSearch::loadTopLevelSystemModules() { - if (!LangOpts.ModulesImplicitMaps) + if (!HSOpts->ImplicitModuleMaps) return; // Load module maps for each of the header search directories. @@ -1342,7 +1366,7 @@ void HeaderSearch::loadTopLevelSystemModules() { } void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { - assert(LangOpts.ModulesImplicitMaps && + assert(HSOpts->ImplicitModuleMaps && "Should not be loading subdirectory module maps"); if (SearchDir.haveSearchedAllModuleMaps()) @@ -1351,10 +1375,12 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); - for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; + for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { - loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), - SearchDir.isFramework()); + bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework"; + if (IsFramework == SearchDir.isFramework()) + loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), + SearchDir.isFramework()); } SearchDir.setSearchedAllModuleMaps(true); |