llvm/clang/lib/Lex/ModuleMap.cpp

//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
//
// 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 defines the ModuleMap implementation, which describes the layout
// of a module as it relates to headers.
//
//===----------------------------------------------------------------------===//

#include "clang/Lex/ModuleMap.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <optional>
#include <string>
#include <system_error>
#include <utility>

usingnamespaceclang;

void ModuleMapCallbacks::anchor() {}

void ModuleMap::resolveLinkAsDependencies(Module *Mod) {}

void ModuleMap::addLinkAsDependency(Module *Mod) {}

Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {}

ModuleMap::ModuleHeaderRole
ModuleMap::headerKindToRole(Module::HeaderKind Kind) {}

bool ModuleMap::isModular(ModuleHeaderRole Role) {}

Module::ExportDecl
ModuleMap::resolveExport(Module *Mod,
                         const Module::UnresolvedExportDecl &Unresolved,
                         bool Complain) const {}

Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
                                   bool Complain) const {}

/// Append to \p Paths the set of paths needed to get to the
/// subframework in which the given module lives.
static void appendSubframeworkPaths(Module *Mod,
                                    SmallVectorImpl<char> &Path) {}

OptionalFileEntryRef ModuleMap::findHeader(
    Module *M, const Module::UnresolvedHeaderDirective &Header,
    SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {}

/// Determine whether the given file name is the name of a builtin
/// header, supplied by Clang to replace, override, or augment existing system
/// headers.
static bool isBuiltinHeaderName(StringRef FileName) {}

/// Determine whether the given module name is the name of a builtin
/// module that is cyclic with a system module  on some platforms.
static bool isBuiltInModuleName(StringRef ModuleName) {}

void ModuleMap::resolveHeader(Module *Mod,
                              const Module::UnresolvedHeaderDirective &Header,
                              bool &NeedsFramework) {}

bool ModuleMap::resolveAsBuiltinHeader(
    Module *Mod, const Module::UnresolvedHeaderDirective &Header) {}

ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
                     const LangOptions &LangOpts, const TargetInfo *Target,
                     HeaderSearch &HeaderInfo)
    :{}

ModuleMap::~ModuleMap() {}

void ModuleMap::setTarget(const TargetInfo &Target) {}

/// "Sanitize" a filename so that it can be used as an identifier.
static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
                                              SmallVectorImpl<char> &Buffer) {}

bool ModuleMap::isBuiltinHeader(FileEntryRef File) {}

bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
                                                        Module *Module) const {}

ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {}

ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(
    FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs) {}

static bool violatesPrivateInclude(Module *RequestingModule,
                                   const FileEntry *IncFileEnt,
                                   ModuleMap::KnownHeader Header) {}

static Module *getTopLevelOrNull(Module *M) {}

void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
                                        bool RequestingModuleIsModuleInterface,
                                        SourceLocation FilenameLoc,
                                        StringRef Filename, FileEntryRef File) {}

static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
                                const ModuleMap::KnownHeader &Old) {}

ModuleMap::KnownHeader ModuleMap::findModuleForHeader(FileEntryRef File,
                                                      bool AllowTextual,
                                                      bool AllowExcluded) {}

ModuleMap::KnownHeader
ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {}

ArrayRef<ModuleMap::KnownHeader>
ModuleMap::findAllModulesForHeader(FileEntryRef File) {}

ArrayRef<ModuleMap::KnownHeader>
ModuleMap::findResolvedModulesForHeader(FileEntryRef File) const {}

bool ModuleMap::isHeaderInUnavailableModule(FileEntryRef Header) const {}

bool ModuleMap::isHeaderUnavailableInModule(
    FileEntryRef Header, const Module *RequestingModule) const {}

Module *ModuleMap::findModule(StringRef Name) const {}

Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
                                           Module *Context) const {}

Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{}

std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
                                                        Module *Parent,
                                                        bool IsFramework,
                                                        bool IsExplicit) {}

Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
                                                           Module *Parent) {}

Module *
ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
                                                           Module *Parent) {}

Module *
ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
                                                       SourceLocation Loc) {}

Module *ModuleMap::createModuleUnitWithKind(SourceLocation Loc, StringRef Name,
                                            Module::ModuleKind Kind) {}

Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
                                                StringRef Name) {}

Module *ModuleMap::createModuleForImplementationUnit(SourceLocation Loc,
                                                     StringRef Name) {}

Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
                                    Module::Header H) {}

/// For a framework module, infer the framework against which we
/// should link.
static void inferFrameworkLink(Module *Mod) {}

Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
                                        bool IsSystem, Module *Parent) {}

Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
                                        Attributes Attrs, Module *Parent) {}

Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
                                        Module *ShadowingModule) {}

void ModuleMap::setUmbrellaHeaderAsWritten(
    Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
    const Twine &PathRelativeToRootModuleDirectory) {}

void ModuleMap::setUmbrellaDirAsWritten(
    Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
    const Twine &PathRelativeToRootModuleDirectory) {}

void ModuleMap::addUnresolvedHeader(Module *Mod,
                                    Module::UnresolvedHeaderDirective Header,
                                    bool &NeedsFramework) {}

void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {}

void ModuleMap::resolveHeaderDirectives(
    Module *Mod, std::optional<const FileEntry *> File) const {}

void ModuleMap::addHeader(Module *Mod, Module::Header Header,
                          ModuleHeaderRole Role, bool Imported) {}

FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const {}

OptionalFileEntryRef
ModuleMap::getContainingModuleMapFile(const Module *Module) const {}

FileID ModuleMap::getModuleMapFileIDForUniquing(const Module *M) const {}

OptionalFileEntryRef
ModuleMap::getModuleMapFileForUniquing(const Module *M) const {}

void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {}

std::error_code
ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {}

void ModuleMap::addAdditionalModuleMapFile(const Module *M,
                                           FileEntryRef ModuleMap) {}

LLVM_DUMP_METHOD void ModuleMap::dump() {}

bool ModuleMap::resolveExports(Module *Mod, bool Complain) {}

bool ModuleMap::resolveUses(Module *Mod, bool Complain) {}

bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {}

//----------------------------------------------------------------------------//
// Module map file parser
//----------------------------------------------------------------------------//

namespace clang {

  /// A token in a module map file.
  struct MMToken {};

  class ModuleMapParser {};

} // namespace clang

SourceLocation ModuleMapParser::consumeToken() {}

void ModuleMapParser::skipUntil(MMToken::TokenKind K) {}

/// Parse a module-id.
///
///   module-id:
///     identifier
///     identifier '.' module-id
///
/// \returns true if an error occurred, false otherwise.
bool ModuleMapParser::parseModuleId(ModuleId &Id) {}

namespace {

  /// Enumerates the known attributes.
  enum AttributeKind {};

} // namespace

/// Private modules are canonicalized as Foo_Private. Clang provides extra
/// module map search logic to find the appropriate private module when PCH
/// is used with implicit module maps. Warn when private modules are written
/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
                                             SourceLocation FrameworkLoc) {}

/// Parse a module declaration.
///
///   module-declaration:
///     'extern' 'module' module-id string-literal
///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
///       { module-member* }
///
///   module-member:
///     requires-declaration
///     header-declaration
///     submodule-declaration
///     export-declaration
///     export-as-declaration
///     link-declaration
///
///   submodule-declaration:
///     module-declaration
///     inferred-submodule-declaration
void ModuleMapParser::parseModuleDecl() {}

/// Parse an extern module declaration.
///
///   extern module-declaration:
///     'extern' 'module' module-id string-literal
void ModuleMapParser::parseExternModuleDecl() {}

/// Whether to add the requirement \p Feature to the module \p M.
///
/// This preserves backwards compatibility for two hacks in the Darwin system
/// module map files:
///
/// 1. The use of 'requires excluded' to make headers non-modular, which
///    should really be mapped to 'textual' now that we have this feature.  We
///    drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
///    true.  Later, this bit will be used to map all the headers inside this
///    module to 'textual'.
///
///    This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
///
/// 2. Removes a bogus cplusplus requirement from IOKit.avc.  This requirement
///    was never correct and causes issues now that we check it, so drop it.
static bool shouldAddRequirement(Module *M, StringRef Feature,
                                 bool &IsRequiresExcludedHack) {}

/// Parse a requires declaration.
///
///   requires-declaration:
///     'requires' feature-list
///
///   feature-list:
///     feature ',' feature-list
///     feature
///
///   feature:
///     '!'[opt] identifier
void ModuleMapParser::parseRequiresDecl() {}

/// Parse a header declaration.
///
///   header-declaration:
///     'textual'[opt] 'header' string-literal
///     'private' 'textual'[opt] 'header' string-literal
///     'exclude' 'header' string-literal
///     'umbrella' 'header' string-literal
///
/// FIXME: Support 'private textual header'.
void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
                                      SourceLocation LeadingLoc) {}

static bool compareModuleHeaders(const Module::Header &A,
                                 const Module::Header &B) {}

/// Parse an umbrella directory declaration.
///
///   umbrella-dir-declaration:
///     umbrella string-literal
void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {}

/// Parse a module export declaration.
///
///   export-declaration:
///     'export' wildcard-module-id
///
///   wildcard-module-id:
///     identifier
///     '*'
///     identifier '.' wildcard-module-id
void ModuleMapParser::parseExportDecl() {}

/// Parse a module export_as declaration.
///
///   export-as-declaration:
///     'export_as' identifier
void ModuleMapParser::parseExportAsDecl() {}

/// Parse a module use declaration.
///
///   use-declaration:
///     'use' wildcard-module-id
void ModuleMapParser::parseUseDecl() {}

/// Parse a link declaration.
///
///   module-declaration:
///     'link' 'framework'[opt] string-literal
void ModuleMapParser::parseLinkDecl() {}

/// Parse a configuration macro declaration.
///
///   module-declaration:
///     'config_macros' attributes[opt] config-macro-list?
///
///   config-macro-list:
///     identifier (',' identifier)?
void ModuleMapParser::parseConfigMacros() {}

/// Format a module-id into a string.
static std::string formatModuleId(const ModuleId &Id) {}

/// Parse a conflict declaration.
///
///   module-declaration:
///     'conflict' module-id ',' string-literal
void ModuleMapParser::parseConflict() {}

/// Parse an inferred module declaration (wildcard modules).
///
///   module-declaration:
///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
///       { inferred-module-member* }
///
///   inferred-module-member:
///     'export' '*'
///     'exclude' identifier
void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {}

/// Parse optional attributes.
///
///   attributes:
///     attribute attributes
///     attribute
///
///   attribute:
///     [ identifier ]
///
/// \param Attrs Will be filled in with the parsed attributes.
///
/// \returns true if an error occurred, false otherwise.
bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {}

/// Parse a module map file.
///
///   module-map-file:
///     module-declaration*
bool ModuleMapParser::parseModuleMapFile() {}

bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
                                   DirectoryEntryRef Dir, FileID ID,
                                   unsigned *Offset,
                                   SourceLocation ExternModuleLoc) {}