summaryrefslogtreecommitdiff
path: root/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/ModuleMap.cpp')
-rw-r--r--lib/Lex/ModuleMap.cpp101
1 files changed, 54 insertions, 47 deletions
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index a7524028a229..3e3215dee82a 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -89,16 +89,13 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
HeaderSearch &HeaderInfo)
: SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
- CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
+ SourceModule(nullptr), NumCreatedModules(0) {
MMapLangOpts.LineComment = true;
}
ModuleMap::~ModuleMap() {
- for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
- IEnd = Modules.end();
- I != IEnd; ++I) {
- delete I->getValue();
- }
+ for (auto &M : Modules)
+ delete M.getValue();
}
void ModuleMap::setTarget(const TargetInfo &Target) {
@@ -154,6 +151,7 @@ static bool isBuiltinHeader(StringRef FileName) {
.Case("limits.h", true)
.Case("stdalign.h", true)
.Case("stdarg.h", true)
+ .Case("stdatomic.h", true)
.Case("stdbool.h", true)
.Case("stddef.h", true)
.Case("stdint.h", true)
@@ -211,29 +209,25 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
static bool violatesPrivateInclude(Module *RequestingModule,
const FileEntry *IncFileEnt,
- ModuleMap::ModuleHeaderRole Role,
- Module *RequestedModule) {
- bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
+ ModuleMap::KnownHeader Header) {
#ifndef NDEBUG
- if (IsPrivateRole) {
+ if (Header.getRole() & ModuleMap::PrivateHeader) {
// Check for consistency between the module header role
// as obtained from the lookup and as obtained from the module.
// This check is not cheap, so enable it only for debugging.
bool IsPrivate = false;
SmallVectorImpl<Module::Header> *HeaderList[] = {
- &RequestedModule->Headers[Module::HK_Private],
- &RequestedModule->Headers[Module::HK_PrivateTextual]};
+ &Header.getModule()->Headers[Module::HK_Private],
+ &Header.getModule()->Headers[Module::HK_PrivateTextual]};
for (auto *Hs : HeaderList)
IsPrivate |=
std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
return H.Entry == IncFileEnt;
}) != Hs->end();
- assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
+ assert(IsPrivate && "inconsistent headers and roles");
}
#endif
- return IsPrivateRole && (!RequestingModule ||
- RequestedModule->getTopLevelModule() !=
- RequestingModule->getTopLevelModule());
+ return !Header.isAccessibleFrom(RequestingModule);
}
static Module *getTopLevelOrNull(Module *M) {
@@ -241,6 +235,7 @@ static Module *getTopLevelOrNull(Module *M) {
}
void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
+ bool RequestingModuleIsModuleInterface,
SourceLocation FilenameLoc,
StringRef Filename,
const FileEntry *File) {
@@ -260,8 +255,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (Known != Headers.end()) {
for (const KnownHeader &Header : Known->second) {
// Remember private headers for later printing of a diagnostic.
- if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
- Header.getModule())) {
+ if (violatesPrivateInclude(RequestingModule, File, Header)) {
Private = Header.getModule();
continue;
}
@@ -303,7 +297,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (LangOpts.ModulesStrictDeclUse) {
Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
<< RequestingModule->getFullModuleName() << Filename;
- } else if (RequestingModule) {
+ } else if (RequestingModule && RequestingModuleIsModuleInterface) {
diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
diag::warn_non_modular_include_in_framework_module :
diag::warn_non_modular_include_in_module;
@@ -343,8 +337,8 @@ ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
ModuleMap::KnownHeader Result;
// Iterate over all modules that 'File' is part of to find the best fit.
for (KnownHeader &H : Known->second) {
- // Prefer a header from the current module over all others.
- if (H.getModule()->getTopLevelModule() == CompilingModule)
+ // Prefer a header from the source module over all others.
+ if (H.getModule()->getTopLevelModule() == SourceModule)
return MakeResult(H);
if (!Result || isBetterKnownHeader(H, Result))
Result = H;
@@ -556,16 +550,10 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
// Create a new module with this name.
Module *Result = new Module(Name, SourceLocation(), Parent,
IsFramework, IsExplicit, NumCreatedModules++);
- if (LangOpts.CurrentModule == Name) {
- SourceModule = Result;
- SourceModuleName = Name;
- }
if (!Parent) {
+ if (LangOpts.CurrentModule == Name)
+ SourceModule = Result;
Modules[Name] = Result;
- if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
- Name == LangOpts.CurrentModule) {
- CompilingModule = Result;
- }
}
return std::make_pair(Result, true);
}
@@ -693,9 +681,10 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
NumCreatedModules++);
InferredModuleAllowedBy[Result] = ModuleMapFile;
Result->IsInferred = true;
- if (LangOpts.CurrentModule == ModuleName) {
- SourceModule = Result;
- SourceModuleName = ModuleName;
+ if (!Parent) {
+ if (LangOpts.CurrentModule == ModuleName)
+ SourceModule = Result;
+ Modules[ModuleName] = Result;
}
Result->IsSystem |= Attrs.IsSystem;
@@ -703,9 +692,6 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Result->Directory = FrameworkDir;
- if (!Parent)
- Modules[ModuleName] = Result;
-
// umbrella header "umbrella-header-name"
//
// The "Headers/" component of the name is implied because this is
@@ -725,13 +711,15 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
= StringRef(FrameworkDir->getName());
llvm::sys::path::append(SubframeworksDirName, "Frameworks");
llvm::sys::path::native(SubframeworksDirName);
- for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
+ vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
+ DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
- if (!StringRef(Dir->path()).endswith(".framework"))
+ if (!StringRef(Dir->getName()).endswith(".framework"))
continue;
- if (const DirectoryEntry *SubframeworkDir
- = FileMgr.getDirectory(Dir->path())) {
+ if (const DirectoryEntry *SubframeworkDir =
+ FileMgr.getDirectory(Dir->getName())) {
// Note: as an egregious but useful hack, we use the real path here and
// check whether it is actually a subdirectory of the parent directory.
// This will not be the case if the 'subframework' is actually a symlink
@@ -774,6 +762,10 @@ void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
Mod->Umbrella = UmbrellaHeader;
Mod->UmbrellaAsWritten = NameAsWritten.str();
UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
+
+ // Notify callbacks that we just added a new header.
+ for (const auto &Cb : Callbacks)
+ Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
}
void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
@@ -812,13 +804,18 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
HeaderList.push_back(KH);
Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
- bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
+ bool isCompilingModuleHeader =
+ LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
isCompilingModuleHeader);
}
+
+ // Notify callbacks that we just added a new header.
+ for (const auto &Cb : Callbacks)
+ Cb->moduleMapAddHeader(Header.Entry->getName());
}
void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
@@ -853,7 +850,7 @@ void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
InferredModuleAllowedBy[M] = ModMap;
}
-void ModuleMap::dump() {
+LLVM_DUMP_METHOD void ModuleMap::dump() {
llvm::errs() << "Modules:";
for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
MEnd = Modules.end();
@@ -920,6 +917,9 @@ Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
if (Loc.isInvalid())
return nullptr;
+ if (UmbrellaDirs.empty() && Headers.empty())
+ return nullptr;
+
// Use the expansion location to determine which module we're in.
FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
if (!ExpansionLoc.isFileID())
@@ -1409,7 +1409,9 @@ void ModuleMapParser::parseModuleDecl() {
// Parse the optional attribute list.
Attributes Attrs;
- parseOptionalAttributes(Attrs);
+ if (parseOptionalAttributes(Attrs))
+ return;
+
// Parse the opening brace.
if (!Tok.is(MMToken::LBrace)) {
@@ -1934,11 +1936,13 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
// uncommonly used Tcl module on Darwin platforms.
std::error_code EC;
SmallVector<Module::Header, 6> Headers;
- for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E;
+ vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
+ for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
I != E && !EC; I.increment(EC)) {
- if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
+ if (const FileEntry *FE =
+ SourceMgr.getFileManager().getFile(I->getName())) {
- Module::Header Header = {I->path(), FE};
+ Module::Header Header = {I->getName(), FE};
Headers.push_back(std::move(Header));
}
}
@@ -2074,7 +2078,9 @@ void ModuleMapParser::parseConfigMacros() {
// Parse the optional attributes.
Attributes Attrs;
- parseOptionalAttributes(Attrs);
+ if (parseOptionalAttributes(Attrs))
+ return;
+
if (Attrs.IsExhaustive && !ActiveModule->Parent) {
ActiveModule->ConfigMacrosExhaustive = true;
}
@@ -2222,7 +2228,8 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
// Parse optional attributes.
Attributes Attrs;
- parseOptionalAttributes(Attrs);
+ if (parseOptionalAttributes(Attrs))
+ return;
if (ActiveModule) {
// Note that we have an inferred submodule.