llvm/clang/lib/Lex/HeaderSearch.cpp

//===- HeaderSearch.cpp - Resolve Header File Locations -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the DirectoryLookup and HeaderSearch interfaces.
//
//===----------------------------------------------------------------------===//

#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 {}

/// CreateHeaderMap - This method returns a HeaderMap for the specified
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *HeaderSearch::CreateHeaderMap(FileEntryRef FE) {}

/// Get filenames for all registered header maps.
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() {}

//===----------------------------------------------------------------------===//
// File lookup within a DirectoryLookup scope
//===----------------------------------------------------------------------===//

/// getName - Return the directory or filename corresponding to this lookup
/// object.
StringRef DirectoryLookup::getName() const {}

OptionalFileEntryRef HeaderSearch::getFileAndSuggestModule(
    StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
    bool IsSystemHeaderDir, Module *RequestingModule,
    ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/,
    bool CacheFailures /*=true*/) {}

/// LookupFile - Lookup the specified file in this search path, returning it
/// if it exists or returning null if not.
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 {}

/// Given a framework directory, find the top-most framework directory.
///
/// \param FileMgr The file manager to use for directory lookups.
/// \param DirName The name of the framework directory.
/// \param SubmodulePath Will be populated with the submodule path from the
/// returned top-level module to the originally named framework.
static OptionalDirectoryEntryRef
getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
                   SmallVectorImpl<std::string> &SubmodulePath) {}

static bool needModuleLookup(Module *RequestingModule,
                             bool HasSuggestedModule) {}

/// DoFrameworkLookup - Do a lookup of the specified file in the current
/// DirectoryLookup, which is a framework directory.
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) {}

//===----------------------------------------------------------------------===//
// Header File Location.
//===----------------------------------------------------------------------===//

/// Return true with a diagnostic if the file that MSVC would have found
/// fails to match the one that Clang would have found with MSVC header search
/// disabled.
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) {}

/// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
/// return null on failure.  isAngled indicates whether the file reference is
/// for system \#include's or not (i.e. using <> instead of ""). Includers, if
/// non-empty, indicates where the \#including file(s) are, in case a relative
/// search is needed. Microsoft mode will pass all \#including files.
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) {}

/// LookupSubframeworkHeader - Look up a subframework for the specified
/// \#include file.  For example, if \#include'ing <HIToolbox/HIToolbox.h> from
/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
/// is a subframework within Carbon.framework.  If so, return the FileEntry
/// for the designated file, otherwise return null.
OptionalFileEntryRef HeaderSearch::LookupSubframeworkHeader(
    StringRef Filename, FileEntryRef ContextFileEnt,
    SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
    Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {}

//===----------------------------------------------------------------------===//
// File Info Management.
//===----------------------------------------------------------------------===//

static bool moduleMembershipNeedsMerge(const HeaderFileInfo *HFI,
                                       ModuleMap::ModuleHeaderRole Role) {}

static void mergeHeaderFileInfoModuleBits(HeaderFileInfo &HFI,
                                          bool isModuleHeader,
                                          bool isTextualModuleHeader) {}

void HeaderFileInfo::mergeModuleMembership(ModuleMap::ModuleHeaderRole Role) {}

/// Merge the header file info provided by \p OtherHFI into the current
/// header file info (\p HFI)
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 {}