summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp273
1 files changed, 139 insertions, 134 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp
index ef322d8..96d3e4b 100644
--- a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp
+++ b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp
@@ -89,7 +89,9 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
HeaderSearch &HeaderInfo)
: SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
- CompilingModule(nullptr), SourceModule(nullptr) {}
+ CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
+ MMapLangOpts.LineComment = true;
+}
ModuleMap::~ModuleMap() {
for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
@@ -163,7 +165,8 @@ static bool isBuiltinHeader(StringRef FileName) {
ModuleMap::HeadersMap::iterator
ModuleMap::findKnownHeader(const FileEntry *File) {
HeadersMap::iterator Known = Headers.find(File);
- if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
+ if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
+ Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
HeaderInfo.loadTopLevelSystemModules();
return Headers.find(File);
@@ -174,6 +177,9 @@ ModuleMap::findKnownHeader(const FileEntry *File) {
ModuleMap::KnownHeader
ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
+ if (UmbrellaDirs.empty())
+ return KnownHeader();
+
const DirectoryEntry *Dir = File->getDir();
assert(Dir && "file in no directory");
@@ -203,35 +209,32 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
return KnownHeader();
}
-// Returns true if RequestingModule directly uses RequestedModule.
-static bool directlyUses(const Module *RequestingModule,
- const Module *RequestedModule) {
- return std::find(RequestingModule->DirectUses.begin(),
- RequestingModule->DirectUses.end(),
- RequestedModule) != RequestingModule->DirectUses.end();
-}
-
static bool violatesPrivateInclude(Module *RequestingModule,
const FileEntry *IncFileEnt,
ModuleMap::ModuleHeaderRole Role,
Module *RequestedModule) {
bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
#ifndef NDEBUG
- // 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]};
- for (auto *Hdrs : HeaderList)
- IsPrivate |=
- std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) {
- return H.Entry == IncFileEnt;
- }) != Hdrs->end();
- assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
+ if (IsPrivateRole) {
+ // 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]};
+ 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");
+ }
#endif
return IsPrivateRole &&
+ // FIXME: Should we map RequestingModule to its top-level module here
+ // too? This check is redundant with the isSubModuleOf check in
+ // diagnoseHeaderInclusion.
RequestedModule->getTopLevelModule() != RequestingModule;
}
@@ -259,7 +262,8 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (Known != Headers.end()) {
for (const KnownHeader &Header : Known->second) {
// If 'File' is part of 'RequestingModule' we can definitely include it.
- if (Header.getModule() == RequestingModule)
+ if (Header.getModule() &&
+ Header.getModule()->isSubModuleOf(RequestingModule))
return;
// Remember private headers for later printing of a diagnostic.
@@ -272,7 +276,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// If uses need to be specified explicitly, we are only allowed to return
// modules that are explicitly used by the requesting module.
if (RequestingModule && LangOpts.ModulesDeclUse &&
- !directlyUses(RequestingModule, Header.getModule())) {
+ !RequestingModule->directlyUses(Header.getModule())) {
NotUsed = Header.getModule();
continue;
}
@@ -286,14 +290,14 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// We have found a header, but it is private.
if (Private) {
- Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
+ Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
<< Filename;
return;
}
// We have found a module, but we don't use it.
if (NotUsed) {
- Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+ Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
<< RequestingModule->getFullModuleName() << Filename;
return;
}
@@ -304,7 +308,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// At this point, only non-modular includes remain.
if (LangOpts.ModulesStrictDeclUse) {
- Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+ Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
<< RequestingModule->getFullModuleName() << Filename;
} else if (RequestingModule) {
diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
@@ -314,43 +318,42 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
}
}
-ModuleMap::KnownHeader
-ModuleMap::findModuleForHeader(const FileEntry *File,
- Module *RequestingModule,
- bool IncludeTextualHeaders) {
- HeadersMap::iterator Known = findKnownHeader(File);
+static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
+ const ModuleMap::KnownHeader &Old) {
+ // Prefer a public header over a private header.
+ if ((New.getRole() & ModuleMap::PrivateHeader) !=
+ (Old.getRole() & ModuleMap::PrivateHeader))
+ return !(New.getRole() & ModuleMap::PrivateHeader);
+
+ // Prefer a non-textual header over a textual header.
+ if ((New.getRole() & ModuleMap::TextualHeader) !=
+ (Old.getRole() & ModuleMap::TextualHeader))
+ return !(New.getRole() & ModuleMap::TextualHeader);
+
+ // Don't have a reason to choose between these. Just keep the first one.
+ return false;
+}
+ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
- if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
+ if (R.getRole() & ModuleMap::TextualHeader)
return ModuleMap::KnownHeader();
return R;
};
+ HeadersMap::iterator Known = findKnownHeader(File);
if (Known != Headers.end()) {
ModuleMap::KnownHeader Result;
-
// Iterate over all modules that 'File' is part of to find the best fit.
- for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
- E = Known->second.end();
- I != E; ++I) {
+ for (KnownHeader &H : Known->second) {
+ // Prefer a header from the current module over all others.
+ if (H.getModule()->getTopLevelModule() == CompilingModule)
+ return MakeResult(H);
// Cannot use a module if it is unavailable.
- if (!I->getModule()->isAvailable())
+ if (!H.getModule()->isAvailable())
continue;
-
- // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
- // module we are looking for.
- if (I->getModule() == RequestingModule)
- return MakeResult(*I);
-
- // If uses need to be specified explicitly, we are only allowed to return
- // modules that are explicitly used by the requesting module.
- if (RequestingModule && LangOpts.ModulesDeclUse &&
- !directlyUses(RequestingModule, I->getModule()))
- continue;
-
- // Prefer a public header over a private header.
- if (!Result || (Result.getRole() & ModuleMap::PrivateHeader))
- Result = *I;
+ if (!Result || isBetterKnownHeader(H, Result))
+ Result = H;
}
return MakeResult(Result);
}
@@ -548,7 +551,7 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
// Create a new module with this name.
Module *Result = new Module(Name, SourceLocation(), Parent,
- IsFramework, IsExplicit);
+ IsFramework, IsExplicit, NumCreatedModules++);
if (LangOpts.CurrentModule == Name) {
SourceModule = Result;
SourceModuleName = Name;
@@ -580,19 +583,28 @@ static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
}
}
-Module *
-ModuleMap::inferFrameworkModule(StringRef ModuleName,
- const DirectoryEntry *FrameworkDir,
- bool IsSystem,
- Module *Parent) {
+Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
+ bool IsSystem, Module *Parent) {
Attributes Attrs;
Attrs.IsSystem = IsSystem;
- return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
+ return inferFrameworkModule(FrameworkDir, Attrs, Parent);
}
-Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
- const DirectoryEntry *FrameworkDir,
+Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Attributes Attrs, Module *Parent) {
+ // Note: as an egregious but useful hack we use the real path here, because
+ // we might be looking at an embedded framework that symlinks out to a
+ // top-level framework, and we need to infer as if we were naming the
+ // top-level framework.
+ StringRef FrameworkDirName =
+ SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
+
+ // In case this is a case-insensitive filesystem, use the canonical
+ // directory name as the ModuleName, since modules are case-sensitive.
+ // FIXME: we should be able to give a fix-it hint for the correct spelling.
+ SmallString<32> ModuleNameStorage;
+ StringRef ModuleName = sanitizeFilenameAsIdentifier(
+ llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
// Check whether we've already found this module.
if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
@@ -605,20 +617,6 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
const FileEntry *ModuleMapFile = nullptr;
if (!Parent) {
// Determine whether we're allowed to infer a module map.
-
- // Note: as an egregious but useful hack we use the real path here, because
- // we might be looking at an embedded framework that symlinks out to a
- // top-level framework, and we need to infer as if we were naming the
- // top-level framework.
- StringRef FrameworkDirName
- = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
-
- // In case this is a case-insensitive filesystem, make sure the canonical
- // directory name matches ModuleName exactly. Modules are case-sensitive.
- // FIXME: we should be able to give a fix-it hint for the correct spelling.
- if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
- return nullptr;
-
bool canInfer = false;
if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
// Figure out the parent path.
@@ -678,7 +676,8 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
return nullptr;
Module *Result = new Module(ModuleName, SourceLocation(), Parent,
- /*IsFramework=*/true, /*IsExplicit=*/false);
+ /*IsFramework=*/true, /*IsExplicit=*/false,
+ NumCreatedModules++);
InferredModuleAllowedBy[Result] = ModuleMapFile;
Result->IsInferred = true;
if (LangOpts.CurrentModule == ModuleName) {
@@ -689,14 +688,16 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
Result->IsSystem |= Attrs.IsSystem;
Result->IsExternC |= Attrs.IsExternC;
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
+ Result->Directory = FrameworkDir;
if (!Parent)
Modules[ModuleName] = Result;
// umbrella header "umbrella-header-name"
- Result->Umbrella = UmbrellaHeader;
- Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
- UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
+ //
+ // The "Headers/" component of the name is implied because this is
+ // a framework module.
+ setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
// export *
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
@@ -711,8 +712,7 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
= StringRef(FrameworkDir->getName());
llvm::sys::path::append(SubframeworksDirName, "Frameworks");
llvm::sys::path::native(SubframeworksDirName);
- for (llvm::sys::fs::directory_iterator
- Dir(SubframeworksDirName.str(), EC), DirEnd;
+ for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
if (!StringRef(Dir->path()).endswith(".framework"))
continue;
@@ -742,10 +742,7 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
continue;
// FIXME: Do we want to warn about subframeworks without umbrella headers?
- SmallString<32> NameBuf;
- inferFrameworkModule(sanitizeFilenameAsIdentifier(
- llvm::sys::path::stem(Dir->path()), NameBuf),
- SubframeworkDir, Attrs, Result);
+ inferFrameworkModule(SubframeworkDir, Attrs, Result);
}
}
@@ -758,14 +755,18 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
return Result;
}
-void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
+void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
+ Twine NameAsWritten) {
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Mod->Umbrella = UmbrellaHeader;
+ Mod->UmbrellaAsWritten = NameAsWritten.str();
UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
}
-void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
+void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
+ Twine NameAsWritten) {
Mod->Umbrella = UmbrellaDir;
+ Mod->UmbrellaAsWritten = NameAsWritten.str();
UmbrellaDirs[UmbrellaDir] = Mod;
}
@@ -850,50 +851,44 @@ void ModuleMap::dump() {
}
bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
- bool HadError = false;
- for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
- Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
- Complain);
+ auto Unresolved = std::move(Mod->UnresolvedExports);
+ Mod->UnresolvedExports.clear();
+ for (auto &UE : Unresolved) {
+ Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
if (Export.getPointer() || Export.getInt())
Mod->Exports.push_back(Export);
else
- HadError = true;
+ Mod->UnresolvedExports.push_back(UE);
}
- Mod->UnresolvedExports.clear();
- return HadError;
+ return !Mod->UnresolvedExports.empty();
}
bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
- bool HadError = false;
- for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
- Module *DirectUse =
- resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
+ auto Unresolved = std::move(Mod->UnresolvedDirectUses);
+ Mod->UnresolvedDirectUses.clear();
+ for (auto &UDU : Unresolved) {
+ Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
if (DirectUse)
Mod->DirectUses.push_back(DirectUse);
else
- HadError = true;
+ Mod->UnresolvedDirectUses.push_back(UDU);
}
- Mod->UnresolvedDirectUses.clear();
- return HadError;
+ return !Mod->UnresolvedDirectUses.empty();
}
bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
- bool HadError = false;
- for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
- Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
- Mod, Complain);
- if (!OtherMod) {
- HadError = true;
- continue;
- }
-
- Module::Conflict Conflict;
- Conflict.Other = OtherMod;
- Conflict.Message = Mod->UnresolvedConflicts[I].Message;
- Mod->Conflicts.push_back(Conflict);
- }
+ auto Unresolved = std::move(Mod->UnresolvedConflicts);
Mod->UnresolvedConflicts.clear();
- return HadError;
+ for (auto &UC : Unresolved) {
+ if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
+ Module::Conflict Conflict;
+ Conflict.Other = OtherMod;
+ Conflict.Message = UC.Message;
+ Mod->Conflicts.push_back(Conflict);
+ } else
+ Mod->UnresolvedConflicts.push_back(UC);
+ }
+ return !Mod->UnresolvedConflicts.empty();
}
Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
@@ -1533,7 +1528,7 @@ void ModuleMapParser::parseModuleDecl() {
/// 'extern' 'module' module-id string-literal
void ModuleMapParser::parseExternModuleDecl() {
assert(Tok.is(MMToken::ExternKeyword));
- consumeToken(); // 'extern' keyword
+ SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
// Parse 'module' keyword.
if (!Tok.is(MMToken::ModuleKeyword)) {
@@ -1565,14 +1560,14 @@ void ModuleMapParser::parseExternModuleDecl() {
if (llvm::sys::path::is_relative(FileNameRef)) {
ModuleMapFileName += Directory->getName();
llvm::sys::path::append(ModuleMapFileName, FileName);
- FileNameRef = ModuleMapFileName.str();
+ FileNameRef = ModuleMapFileName;
}
if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Map.parseModuleMapFile(
File, /*IsSystem=*/false,
Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
? Directory
- : File->getDir());
+ : File->getDir(), ExternLoc);
}
/// \brief Parse a requires declaration.
@@ -1712,7 +1707,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// Check whether this file is in the public headers.
llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName.str());
+ llvm::sys::path::append(FullPathName, RelativePathName);
File = SourceMgr.getFileManager().getFile(FullPathName);
if (!File) {
@@ -1722,13 +1717,13 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
FullPathName.resize(FullPathLength);
llvm::sys::path::append(RelativePathName, "PrivateHeaders",
Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName.str());
+ llvm::sys::path::append(FullPathName, RelativePathName);
File = SourceMgr.getFileManager().getFile(FullPathName);
}
} else {
// Lookup for normal headers.
llvm::sys::path::append(RelativePathName, Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName.str());
+ llvm::sys::path::append(FullPathName, RelativePathName);
File = SourceMgr.getFileManager().getFile(FullPathName);
// If this is a system module with a top-level header, this header
@@ -1744,7 +1739,13 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// If Clang supplies this header but the underlying system does not,
// just silently swap in our builtin version. Otherwise, we'll end
// up adding both (later).
- if (!File && BuiltinFile) {
+ //
+ // For local visibility, entirely replace the system file with our
+ // one and textually include the system one. We need to pass macros
+ // from our header to the system one if we #include_next it.
+ //
+ // FIXME: Can we do this in all cases?
+ if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
File = BuiltinFile;
RelativePathName = BuiltinPathName;
BuiltinFile = nullptr;
@@ -1764,7 +1765,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
HadError = true;
} else {
// Record this umbrella header.
- Map.setUmbrellaHeader(ActiveModule, File);
+ Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
}
} else if (LeadingToken == MMToken::ExcludeKeyword) {
Module::Header H = {RelativePathName.str(), File};
@@ -1846,7 +1847,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
// Record this umbrella directory.
- Map.setUmbrellaDir(ActiveModule, Dir);
+ Map.setUmbrellaDir(ActiveModule, Dir, DirName);
}
/// \brief Parse a module export declaration.
@@ -1897,18 +1898,21 @@ void ModuleMapParser::parseExportDecl() {
ActiveModule->UnresolvedExports.push_back(Unresolved);
}
-/// \brief Parse a module uses declaration.
+/// \brief Parse a module use declaration.
///
-/// uses-declaration:
-/// 'uses' wildcard-module-id
+/// use-declaration:
+/// 'use' wildcard-module-id
void ModuleMapParser::parseUseDecl() {
assert(Tok.is(MMToken::UseKeyword));
- consumeToken();
+ auto KWLoc = consumeToken();
// Parse the module-id.
ModuleId ParsedModuleId;
parseModuleId(ParsedModuleId);
- ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
+ if (ActiveModule->Parent)
+ Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
+ else
+ ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
}
/// \brief Parse a link declaration.
@@ -2315,7 +2319,8 @@ bool ModuleMapParser::parseModuleMapFile() {
}
bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *Dir) {
+ const DirectoryEntry *Dir,
+ SourceLocation ExternModuleLoc) {
llvm::DenseMap<const FileEntry *, bool>::iterator Known
= ParsedModuleMap.find(File);
if (Known != ParsedModuleMap.end())
@@ -2323,7 +2328,7 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
assert(Target && "Missing target information");
auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
- FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
+ FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
if (!Buffer)
return ParsedModuleMap[File] = true;
OpenPOWER on IntegriCloud