#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Capacity.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <string>
#include <system_error>
#include <utility>
usingnamespaceclang;
#define DEBUG_TYPE …
ALWAYS_ENABLED_STATISTIC(NumIncluded, "Number of attempted #includes.");
ALWAYS_ENABLED_STATISTIC(
NumMultiIncludeFileOptzn,
"Number of #includes skipped due to the multi-include optimization.");
ALWAYS_ENABLED_STATISTIC(NumFrameworkLookups, "Number of framework lookups.");
ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
"Number of subframework lookups.");
const IdentifierInfo *
HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) { … }
ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() = default;
HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
SourceManager &SourceMgr, DiagnosticsEngine &Diags,
const LangOptions &LangOpts,
const TargetInfo *Target)
: … { … }
void HeaderSearch::PrintStats() { … }
void HeaderSearch::SetSearchPaths(
std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx,
unsigned int systemDirIdx,
llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) { … }
void HeaderSearch::AddSearchPath(const DirectoryLookup &dir, bool isAngled) { … }
std::vector<bool> HeaderSearch::computeUserEntryUsage() const { … }
std::vector<bool> HeaderSearch::collectVFSUsageAndClear() const { … }
const HeaderMap *HeaderSearch::CreateHeaderMap(FileEntryRef FE) { … }
void HeaderSearch::getHeaderMapFileNames(
SmallVectorImpl<std::string> &Names) const { … }
std::string HeaderSearch::getCachedModuleFileName(Module *Module) { … }
std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
bool FileMapOnly) { … }
std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) { … }
std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
StringRef ModuleMapPath) { … }
std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
StringRef ModuleMapPath,
StringRef CachePath) { … }
Module *HeaderSearch::lookupModule(StringRef ModuleName,
SourceLocation ImportLoc, bool AllowSearch,
bool AllowExtraModuleMapSearch) { … }
Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
SourceLocation ImportLoc,
bool AllowExtraModuleMapSearch) { … }
void HeaderSearch::indexInitialHeaderMaps() { … }
StringRef DirectoryLookup::getName() const { … }
OptionalFileEntryRef HeaderSearch::getFileAndSuggestModule(
StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
bool IsSystemHeaderDir, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool OpenFile ,
bool CacheFailures ) { … }
OptionalFileEntryRef DirectoryLookup::LookupFile(
StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName,
bool OpenFile) const { … }
static OptionalDirectoryEntryRef
getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
SmallVectorImpl<std::string> &SubmodulePath) { … }
static bool needModuleLookup(Module *RequestingModule,
bool HasSuggestedModule) { … }
OptionalFileEntryRef DirectoryLookup::DoFrameworkLookup(
StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const { … }
void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
ConstSearchDirIterator HitIt,
SourceLocation Loc) { … }
void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) { … }
void HeaderSearch::setTarget(const TargetInfo &Target) { … }
static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
OptionalFileEntryRef MSFE,
const FileEntry *FE,
SourceLocation IncludeLoc) { … }
static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) { … }
static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader,
SmallVectorImpl<char> &FrameworkName,
SmallVectorImpl<char> &IncludeSpelling) { … }
static void
diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc,
StringRef Includer, StringRef IncludeFilename,
FileEntryRef IncludeFE, bool isAngled = false,
bool FoundByHeaderMap = false) { … }
OptionalFileEntryRef HeaderSearch::LookupFile(
StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
bool BuildSystemModule, bool OpenFile, bool CacheFailures) { … }
OptionalFileEntryRef HeaderSearch::LookupSubframeworkHeader(
StringRef Filename, FileEntryRef ContextFileEnt,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) { … }
static bool moduleMembershipNeedsMerge(const HeaderFileInfo *HFI,
ModuleMap::ModuleHeaderRole Role) { … }
static void mergeHeaderFileInfoModuleBits(HeaderFileInfo &HFI,
bool isModuleHeader,
bool isTextualModuleHeader) { … }
void HeaderFileInfo::mergeModuleMembership(ModuleMap::ModuleHeaderRole Role) { … }
static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
const HeaderFileInfo &OtherHFI) { … }
HeaderFileInfo &HeaderSearch::getFileInfo(FileEntryRef FE) { … }
const HeaderFileInfo *HeaderSearch::getExistingFileInfo(FileEntryRef FE) const { … }
const HeaderFileInfo *
HeaderSearch::getExistingLocalFileInfo(FileEntryRef FE) const { … }
bool HeaderSearch::isFileMultipleIncludeGuarded(FileEntryRef File) const { … }
void HeaderSearch::MarkFileModuleHeader(FileEntryRef FE,
ModuleMap::ModuleHeaderRole Role,
bool isCompilingModuleHeader) { … }
bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
FileEntryRef File, bool isImport,
bool ModulesEnabled, Module *M,
bool &IsFirstIncludeOfFile) { … }
size_t HeaderSearch::getTotalMemory() const { … }
unsigned HeaderSearch::searchDirIdx(const DirectoryLookup &DL) const { … }
StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { … }
StringRef HeaderSearch::getIncludeNameForHeader(const FileEntry *File) const { … }
bool HeaderSearch::hasModuleMap(StringRef FileName,
const DirectoryEntry *Root,
bool IsSystem) { … }
ModuleMap::KnownHeader
HeaderSearch::findModuleForHeader(FileEntryRef File, bool AllowTextual,
bool AllowExcluded) const { … }
ArrayRef<ModuleMap::KnownHeader>
HeaderSearch::findAllModulesForHeader(FileEntryRef File) const { … }
ArrayRef<ModuleMap::KnownHeader>
HeaderSearch::findResolvedModulesForHeader(FileEntryRef File) const { … }
static bool suggestModule(HeaderSearch &HS, FileEntryRef File,
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule) { … }
bool HeaderSearch::findUsableModuleForHeader(
FileEntryRef File, const DirectoryEntry *Root, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) { … }
bool HeaderSearch::findUsableModuleForFrameworkHeader(
FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) { … }
static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File,
FileManager &FileMgr,
DiagnosticsEngine &Diags) { … }
bool HeaderSearch::loadModuleMapFile(FileEntryRef File, bool IsSystem,
FileID ID, unsigned *Offset,
StringRef OriginalModuleMapFile) { … }
HeaderSearch::LoadModuleMapResult
HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
DirectoryEntryRef Dir, FileID ID,
unsigned *Offset) { … }
OptionalFileEntryRef
HeaderSearch::lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework) { … }
Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
bool IsSystem) { … }
HeaderSearch::LoadModuleMapResult
HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
bool IsFramework) { … }
HeaderSearch::LoadModuleMapResult
HeaderSearch::loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
bool IsFramework) { … }
void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { … }
void HeaderSearch::loadTopLevelSystemModules() { … }
void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { … }
std::string HeaderSearch::suggestPathToFileForDiagnostics(
FileEntryRef File, llvm::StringRef MainFile, bool *IsAngled) const { … }
std::string HeaderSearch::suggestPathToFileForDiagnostics(
llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
bool *IsAngled) const { … }