|
|
|
|
@@ -1051,7 +1051,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
|
|
|
|
|
bool IsFrameworkDir = Parent.ends_with(".framework");
|
|
|
|
|
if (OptionalFileEntryRef ModMapFile =
|
|
|
|
|
HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
|
|
|
|
|
parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
|
|
|
|
|
loadModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
|
|
|
|
|
inferred = InferredDirectories.find(*ParentDir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1354,7 +1354,7 @@ std::error_code
|
|
|
|
|
ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {
|
|
|
|
|
StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
|
|
|
|
|
|
|
|
|
|
// Do not canonicalize within the framework; the module map parser expects
|
|
|
|
|
// Do not canonicalize within the framework; the module map loader expects
|
|
|
|
|
// Modules/ not Versions/A/Modules.
|
|
|
|
|
if (llvm::sys::path::filename(Dir) == "Modules") {
|
|
|
|
|
StringRef Parent = llvm::sys::path::parent_path(Dir);
|
|
|
|
|
@@ -1453,11 +1453,11 @@ bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
// Module map file parser
|
|
|
|
|
// Module map file loader
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
|
class ModuleMapParser {
|
|
|
|
|
class ModuleMapLoader {
|
|
|
|
|
modulemap::ModuleMapFile &MMF;
|
|
|
|
|
SourceManager &SourceMgr;
|
|
|
|
|
|
|
|
|
|
@@ -1467,7 +1467,7 @@ class ModuleMapParser {
|
|
|
|
|
/// The current module map file.
|
|
|
|
|
FileID ModuleMapFID;
|
|
|
|
|
|
|
|
|
|
/// Source location of most recent parsed module declaration
|
|
|
|
|
/// Source location of most recent loaded module declaration
|
|
|
|
|
SourceLocation CurrModuleDeclLoc;
|
|
|
|
|
|
|
|
|
|
/// The directory that file names in this module map file should
|
|
|
|
|
@@ -1515,13 +1515,13 @@ class ModuleMapParser {
|
|
|
|
|
using Attributes = ModuleMap::Attributes;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ModuleMapParser(modulemap::ModuleMapFile &MMF, SourceManager &SourceMgr,
|
|
|
|
|
ModuleMapLoader(modulemap::ModuleMapFile &MMF, SourceManager &SourceMgr,
|
|
|
|
|
DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID,
|
|
|
|
|
DirectoryEntryRef Directory, bool IsSystem)
|
|
|
|
|
: MMF(MMF), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
|
|
|
|
|
ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
|
|
|
|
|
|
|
|
|
|
bool parseModuleMapFile();
|
|
|
|
|
bool loadModuleMapFile();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace clang
|
|
|
|
|
@@ -1530,7 +1530,7 @@ public:
|
|
|
|
|
/// 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 StartLoc) {
|
|
|
|
|
void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {
|
|
|
|
|
auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
|
|
|
|
|
const Module *M, SourceRange ReplLoc) {
|
|
|
|
|
auto D = Diags.Report(ActiveModule->DefinitionLoc,
|
|
|
|
|
@@ -1584,7 +1584,7 @@ void ModuleMapParser::diagnosePrivateModules(SourceLocation StartLoc) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleModuleDecl(const modulemap::ModuleDecl &MD) {
|
|
|
|
|
void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
|
|
|
|
|
if (MD.Id.front().first == "*")
|
|
|
|
|
return handleInferredModuleDecl(MD);
|
|
|
|
|
|
|
|
|
|
@@ -1763,7 +1763,7 @@ void ModuleMapParser::handleModuleDecl(const modulemap::ModuleDecl &MD) {
|
|
|
|
|
ActiveModule = PreviousActiveModule;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleExternModuleDecl(
|
|
|
|
|
void ModuleMapLoader::handleExternModuleDecl(
|
|
|
|
|
const modulemap::ExternModuleDecl &EMD) {
|
|
|
|
|
StringRef FileNameRef = EMD.Path;
|
|
|
|
|
SmallString<128> ModuleMapFileName;
|
|
|
|
|
@@ -1773,7 +1773,7 @@ void ModuleMapParser::handleExternModuleDecl(
|
|
|
|
|
FileNameRef = ModuleMapFileName;
|
|
|
|
|
}
|
|
|
|
|
if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
|
|
|
|
|
Map.parseModuleMapFile(
|
|
|
|
|
Map.loadModuleMapFile(
|
|
|
|
|
*File, IsSystem,
|
|
|
|
|
Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
|
|
|
|
|
? Directory
|
|
|
|
|
@@ -1810,7 +1810,7 @@ static bool shouldAddRequirement(Module *M, StringRef Feature,
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
|
|
|
|
|
void ModuleMapLoader::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
|
|
|
|
|
|
|
|
|
|
for (const modulemap::RequiresFeature &RF : RD.Features) {
|
|
|
|
|
bool IsRequiresExcludedHack = false;
|
|
|
|
|
@@ -1828,7 +1828,7 @@ void ModuleMapParser::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleHeaderDecl(const modulemap::HeaderDecl &HD) {
|
|
|
|
|
void ModuleMapLoader::handleHeaderDecl(const modulemap::HeaderDecl &HD) {
|
|
|
|
|
// We've already consumed the first token.
|
|
|
|
|
ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
|
|
|
|
|
|
|
|
|
|
@@ -1887,7 +1887,7 @@ static bool compareModuleHeaders(const Module::Header &A,
|
|
|
|
|
return A.NameAsWritten < B.NameAsWritten;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleUmbrellaDirDecl(
|
|
|
|
|
void ModuleMapLoader::handleUmbrellaDirDecl(
|
|
|
|
|
const modulemap::UmbrellaDirDecl &UDD) {
|
|
|
|
|
std::string DirName = std::string(UDD.Path);
|
|
|
|
|
std::string DirNameAsWritten = DirName;
|
|
|
|
|
@@ -1919,7 +1919,7 @@ void ModuleMapParser::handleUmbrellaDirDecl(
|
|
|
|
|
|
|
|
|
|
if (UsesRequiresExcludedHack.count(ActiveModule)) {
|
|
|
|
|
// Mark this header 'textual' (see doc comment for
|
|
|
|
|
// ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
|
|
|
|
|
// ModuleMapLoader::UsesRequiresExcludedHack). Although iterating over the
|
|
|
|
|
// directory is relatively expensive, in practice this only applies to the
|
|
|
|
|
// uncommonly used Tcl module on Darwin platforms.
|
|
|
|
|
std::error_code EC;
|
|
|
|
|
@@ -1953,12 +1953,12 @@ void ModuleMapParser::handleUmbrellaDirDecl(
|
|
|
|
|
Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleExportDecl(const modulemap::ExportDecl &ED) {
|
|
|
|
|
void ModuleMapLoader::handleExportDecl(const modulemap::ExportDecl &ED) {
|
|
|
|
|
Module::UnresolvedExportDecl Unresolved = {ED.Location, ED.Id, ED.Wildcard};
|
|
|
|
|
ActiveModule->UnresolvedExports.push_back(Unresolved);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
|
|
|
|
|
void ModuleMapLoader::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
|
|
|
|
|
auto ModName = EAD.Id.front();
|
|
|
|
|
|
|
|
|
|
if (!ActiveModule->ExportAsModule.empty()) {
|
|
|
|
|
@@ -1976,19 +1976,19 @@ void ModuleMapParser::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
|
|
|
|
|
Map.addLinkAsDependency(ActiveModule);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleUseDecl(const modulemap::UseDecl &UD) {
|
|
|
|
|
void ModuleMapLoader::handleUseDecl(const modulemap::UseDecl &UD) {
|
|
|
|
|
if (ActiveModule->Parent)
|
|
|
|
|
Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);
|
|
|
|
|
else
|
|
|
|
|
ActiveModule->UnresolvedDirectUses.push_back(UD.Id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleLinkDecl(const modulemap::LinkDecl &LD) {
|
|
|
|
|
void ModuleMapLoader::handleLinkDecl(const modulemap::LinkDecl &LD) {
|
|
|
|
|
ActiveModule->LinkLibraries.push_back(
|
|
|
|
|
Module::LinkLibrary(std::string{LD.Library}, LD.Framework));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleConfigMacros(
|
|
|
|
|
void ModuleMapLoader::handleConfigMacros(
|
|
|
|
|
const modulemap::ConfigMacrosDecl &CMD) {
|
|
|
|
|
if (ActiveModule->Parent) {
|
|
|
|
|
Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);
|
|
|
|
|
@@ -2004,7 +2004,7 @@ void ModuleMapParser::handleConfigMacros(
|
|
|
|
|
CMD.Macros.begin(), CMD.Macros.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleConflict(const modulemap::ConflictDecl &CD) {
|
|
|
|
|
void ModuleMapLoader::handleConflict(const modulemap::ConflictDecl &CD) {
|
|
|
|
|
Module::UnresolvedConflict Conflict;
|
|
|
|
|
|
|
|
|
|
Conflict.Id = CD.Id;
|
|
|
|
|
@@ -2013,7 +2013,7 @@ void ModuleMapParser::handleConflict(const modulemap::ConflictDecl &CD) {
|
|
|
|
|
ActiveModule->UnresolvedConflicts.push_back(Conflict);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModuleMapParser::handleInferredModuleDecl(
|
|
|
|
|
void ModuleMapLoader::handleInferredModuleDecl(
|
|
|
|
|
const modulemap::ModuleDecl &MD) {
|
|
|
|
|
SourceLocation StarLoc = MD.Id.front().second;
|
|
|
|
|
|
|
|
|
|
@@ -2103,7 +2103,7 @@ void ModuleMapParser::handleInferredModuleDecl(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ModuleMapParser::parseModuleMapFile() {
|
|
|
|
|
bool ModuleMapLoader::loadModuleMapFile() {
|
|
|
|
|
for (const auto &Decl : MMF.Decls) {
|
|
|
|
|
std::visit(
|
|
|
|
|
llvm::makeVisitor(
|
|
|
|
|
@@ -2116,14 +2116,14 @@ bool ModuleMapParser::parseModuleMapFile() {
|
|
|
|
|
return HadError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
|
|
|
|
|
DirectoryEntryRef Dir, FileID ID,
|
|
|
|
|
unsigned *Offset,
|
|
|
|
|
SourceLocation ExternModuleLoc) {
|
|
|
|
|
bool ModuleMap::loadModuleMapFile(FileEntryRef File, bool IsSystem,
|
|
|
|
|
DirectoryEntryRef Dir, FileID ID,
|
|
|
|
|
unsigned *Offset,
|
|
|
|
|
SourceLocation ExternModuleLoc) {
|
|
|
|
|
assert(Target && "Missing target information");
|
|
|
|
|
llvm::DenseMap<const FileEntry *, bool>::iterator Known
|
|
|
|
|
= ParsedModuleMap.find(File);
|
|
|
|
|
if (Known != ParsedModuleMap.end())
|
|
|
|
|
llvm::DenseMap<const FileEntry *, bool>::iterator Known =
|
|
|
|
|
LoadedModuleMap.find(File);
|
|
|
|
|
if (Known != LoadedModuleMap.end())
|
|
|
|
|
return Known->second;
|
|
|
|
|
|
|
|
|
|
// If the module map file wasn't already entered, do so now.
|
|
|
|
|
@@ -2136,7 +2136,7 @@ bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
|
|
|
|
|
assert(Target && "Missing target information");
|
|
|
|
|
std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
|
|
|
|
|
if (!Buffer)
|
|
|
|
|
return ParsedModuleMap[File] = true;
|
|
|
|
|
return LoadedModuleMap[File] = true;
|
|
|
|
|
assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
|
|
|
|
|
"invalid buffer offset");
|
|
|
|
|
|
|
|
|
|
@@ -2144,12 +2144,13 @@ bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
|
|
|
|
|
modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, Offset);
|
|
|
|
|
bool Result = false;
|
|
|
|
|
if (MMF) {
|
|
|
|
|
ModuleMapParser Parser(*MMF, SourceMgr, Diags, *this, ID, Dir, IsSystem);
|
|
|
|
|
Result = Parser.parseModuleMapFile();
|
|
|
|
|
ModuleMapLoader Loader(*MMF, SourceMgr, Diags, *this, ID, Dir, IsSystem);
|
|
|
|
|
Result = Loader.loadModuleMapFile();
|
|
|
|
|
}
|
|
|
|
|
ParsedModuleMap[File] = Result;
|
|
|
|
|
LoadedModuleMap[File] = Result;
|
|
|
|
|
|
|
|
|
|
// Notify callbacks that we parsed it.
|
|
|
|
|
// Notify callbacks that we observed it.
|
|
|
|
|
// FIXME: We should only report module maps that were actually used.
|
|
|
|
|
for (const auto &Cb : Callbacks)
|
|
|
|
|
Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);
|
|
|
|
|
|
|
|
|
|
|