summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/Tools.cpp6
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp3
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp54
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp13
-rw-r--r--clang/lib/Serialization/ASTReader.cpp58
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp5
-rw-r--r--clang/lib/Serialization/ModuleManager.cpp2
8 files changed, 113 insertions, 31 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 822d55b7cbf..d8f3edd8957 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3833,7 +3833,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// definitions.
Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
- // -fmodule-cache-path specifies where our module files should be written.
+ // -fmodule-file can be used to specify files containing precompiled modules.
+ Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
+
+ // -fmodule-cache-path specifies where our implicitly-built module files
+ // should be written.
SmallString<128> ModuleCachePath;
if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
ModuleCachePath = A->getValue();
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 8742a54c01c..19fafa3370a 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -2776,7 +2776,8 @@ struct PCHLocatorInfo {
static bool PCHLocator(serialization::ModuleFile &M, void *UserData) {
PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData);
switch (M.Kind) {
- case serialization::MK_Module:
+ case serialization::MK_ImplicitModule:
+ case serialization::MK_ExplicitModule:
return true; // skip dependencies.
case serialization::MK_PCH:
Info.Mod = &M;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index e1803d0f311..ba0743abd26 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1040,7 +1040,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
// Try to read the module file, now that we've compiled it.
ASTReader::ASTReadResult ReadResult =
ImportingInstance.getModuleManager()->ReadAST(
- ModuleFileName, serialization::MK_Module, ImportLoc,
+ ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
ModuleLoadCapabilities);
if (ReadResult == ASTReader::OutOfDate &&
@@ -1268,6 +1268,53 @@ void CompilerInstance::createModuleManager() {
}
ModuleLoadResult
+CompilerInstance::loadModuleFile(StringRef FileName, SourceLocation Loc) {
+ if (!ModuleManager)
+ createModuleManager();
+ if (!ModuleManager)
+ return ModuleLoadResult();
+
+ // Load the module if this is the first time we've been told about this file.
+ auto *MF = ModuleManager->getModuleManager().lookup(FileName);
+ if (!MF) {
+ struct ReadModuleNameListener : ASTReaderListener {
+ std::function<void(StringRef)> OnRead;
+ ReadModuleNameListener(std::function<void(StringRef)> F) : OnRead(F) {}
+ void ReadModuleName(StringRef ModuleName) override { OnRead(ModuleName); }
+ };
+
+ // Register listener to track the modules that are loaded by explicitly
+ // loading a module file. We suppress any attempts to implicitly load
+ // module files for any such module.
+ ASTReader::ListenerScope OnReadModuleName(
+ *ModuleManager,
+ llvm::make_unique<ReadModuleNameListener>([&](StringRef ModuleName) {
+ auto &PP = getPreprocessor();
+ auto *NameII = PP.getIdentifierInfo(ModuleName);
+ auto *Module = PP.getHeaderSearchInfo().lookupModule(ModuleName, false);
+ if (!KnownModules.insert(std::make_pair(NameII, Module)).second)
+ getDiagnostics().Report(Loc, diag::err_module_already_loaded)
+ << ModuleName << FileName;
+ }));
+
+ if (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, Loc,
+ ASTReader::ARR_None) != ASTReader::Success)
+ return ModuleLoadResult();
+
+ MF = ModuleManager->getModuleManager().lookup(FileName);
+ assert(MF && "unexpectedly failed to load module file");
+ }
+
+ if (MF->ModuleName.empty()) {
+ getDiagnostics().Report(Loc, diag::err_module_file_not_module)
+ << FileName;
+ return ModuleLoadResult();
+ }
+ auto *Module = PP->getHeaderSearchInfo().lookupModule(MF->ModuleName, false);
+ return ModuleLoadResult(Module, false);
+}
+
+ModuleLoadResult
CompilerInstance::loadModule(SourceLocation ImportLoc,
ModuleIdPath Path,
Module::NameVisibilityKind Visibility,
@@ -1330,8 +1377,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// Try to load the module file.
unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
- switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module,
- ImportLoc, ARRFlags)) {
+ switch (ModuleManager->ReadAST(ModuleFileName,
+ serialization::MK_ImplicitModule, ImportLoc,
+ ARRFlags)) {
case ASTReader::Success:
break;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 373842d2381..2c4118c2792 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -838,7 +838,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups);
Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
-
+ Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
+
Opts.CodeCompleteOpts.IncludeMacros
= Args.hasArg(OPT_code_completion_macros);
Opts.CodeCompleteOpts.IncludeCodePatterns
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 8760f5094d4..1c9384218ad 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -321,7 +321,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
// FIXME: should not overwrite ASTMutationListener when parsing model files?
if (!isModelParsingAction())
CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
-
+
if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
// Convert headers to PCH and chain them.
IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
@@ -383,6 +383,17 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
"doesn't support modules");
}
+ // If we were asked to load any module files, do so now. Don't make any names
+ // from those modules visible.
+ for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
+ // FIXME: Use a better source location here. Perhaps inject something
+ // into the predefines buffer to represent these module files.
+ if (!CI.loadModuleFile(ModuleFile,
+ CI.getSourceManager().getLocForStartOfFile(
+ CI.getSourceManager().getMainFileID())))
+ goto failure;
+ }
+
// If there is a layout overrides file, attach an external AST source that
// provides the layouts from that file.
if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 3a6e6551dbf..f3181546320 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -389,14 +389,14 @@ bool PCHValidator::ReadDiagnosticOptions(
// If the original import came from a file explicitly generated by the user,
// don't check the diagnostic mappings.
// FIXME: currently this is approximated by checking whether this is not a
- // module import.
+ // module import of an implicitly-loaded module file.
// Note: ModuleMgr.rbegin() may not be the current module, but it must be in
// the transitive closure of its imports, since unrelated modules cannot be
// imported until after this module finishes validation.
ModuleFile *TopImport = *ModuleMgr.rbegin();
while (!TopImport->ImportedBy.empty())
TopImport = TopImport->ImportedBy[0];
- if (TopImport->Kind != MK_Module)
+ if (TopImport->Kind != MK_ImplicitModule)
return false;
StringRef ModuleName = TopImport->ModuleName;
@@ -781,7 +781,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
}
}
- if (F.Kind == MK_Module) {
+ if (F.Kind == MK_ImplicitModule || F.Kind == MK_ExplicitModule) {
// Macro definitions are stored from newest to oldest, so reverse them
// before registering them.
llvm::SmallVector<unsigned, 8> MacroSizes;
@@ -1238,7 +1238,8 @@ bool ASTReader::ReadSLocEntry(int ID) {
SrcMgr::CharacteristicKind
FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
- if (IncludeLoc.isInvalid() && F->Kind == MK_Module) {
+ if (IncludeLoc.isInvalid() &&
+ (F->Kind == MK_ImplicitModule || F->Kind == MK_ExplicitModule)) {
IncludeLoc = getImportLocation(F);
}
unsigned Code = SLocEntryCursor.ReadCode();
@@ -1284,7 +1285,7 @@ std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {
// Find which module file this entry lands in.
ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second;
- if (M->Kind != MK_Module)
+ if (M->Kind != MK_ImplicitModule && M->Kind != MK_ExplicitModule)
return std::make_pair(SourceLocation(), "");
// FIXME: Can we map this down to a particular submodule? That would be
@@ -1773,7 +1774,8 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
const PendingMacroInfo &PMInfo) {
assert(II);
- if (PMInfo.M->Kind != MK_Module) {
+ if (PMInfo.M->Kind != MK_ImplicitModule &&
+ PMInfo.M->Kind != MK_ExplicitModule) {
installPCHMacroDirectives(II, *PMInfo.M,
PMInfo.PCHMacroData.MacroDirectivesOffset);
return;
@@ -1797,7 +1799,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
ModuleFile &M, uint64_t Offset) {
- assert(M.Kind != MK_Module);
+ assert(M.Kind != MK_ImplicitModule && M.Kind != MK_ExplicitModule);
BitstreamCursor &Cursor = M.MacroCursor;
SavedStreamPosition SavedPosition(Cursor);
@@ -2279,7 +2281,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
unsigned N = NumUserInputs;
if (ValidateSystemInputs ||
- (HSOpts.ModulesValidateOncePerBuildSession && F.Kind == MK_Module))
+ (HSOpts.ModulesValidateOncePerBuildSession &&
+ F.Kind == MK_ImplicitModule))
N = NumInputs;
for (unsigned I = 0; I < N; ++I) {
@@ -3191,7 +3194,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
break;
case IMPORTED_MODULES: {
- if (F.Kind != MK_Module) {
+ if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) {
// If we aren't loading a module (which has its own exports), make
// all of the imported modules visible.
// FIXME: Deal with macros-only imports.
@@ -3289,29 +3292,40 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
unsigned Idx = 0;
F.ModuleMapPath = ReadString(Record, Idx);
+ if (F.Kind == MK_ExplicitModule) {
+ // For an explicitly-loaded module, we don't care whether the original
+ // module map file exists or matches.
+ return Success;
+ }
+
// Try to resolve ModuleName in the current header search context and
// verify that it is found in the same module map file as we saved. If the
// top-level AST file is a main file, skip this check because there is no
// usable header search context.
assert(!F.ModuleName.empty() &&
- "MODULE_NAME should come before MOUDLE_MAP_FILE");
- if (F.Kind == MK_Module && (*ModuleMgr.begin())->Kind != MK_MainFile) {
+ "MODULE_NAME should come before MODULE_MAP_FILE");
+ if (F.Kind == MK_ImplicitModule &&
+ (*ModuleMgr.begin())->Kind != MK_MainFile) {
+ // An implicitly-loaded module file should have its module listed in some
+ // module map file that we've already loaded.
Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
- if (!M) {
+ auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+ const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
+ if (!ModMap) {
assert(ImportedBy && "top-level import should be verified");
if ((ClientLoadCapabilities & ARR_Missing) == 0)
- Diag(diag::err_imported_module_not_found)
- << F.ModuleName << ImportedBy->FileName;
+ Diag(diag::err_imported_module_not_found) << F.ModuleName << F.FileName
+ << ImportedBy->FileName
+ << F.ModuleMapPath;
return Missing;
}
+ assert(M->Name == F.ModuleName && "found module with different name");
+
// Check the primary module map file.
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
- const FileEntry *ModMap = Map.getModuleMapFileForUniquing(M);
if (StoredModMap == nullptr || StoredModMap != ModMap) {
assert(ModMap && "found module is missing module map file");
- assert(M->Name == F.ModuleName && "found module with different name");
assert(ImportedBy && "top-level import should be verified");
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
Diag(diag::err_imported_module_modmap_changed)
@@ -3696,7 +3710,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
// in the filesystem).
for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {
ImportedModule &M = Loaded[I];
- if (M.Mod->Kind == MK_Module) {
+ if (M.Mod->Kind == MK_ImplicitModule) {
updateModuleTimestamp(*M.Mod);
}
}
@@ -3729,7 +3743,7 @@ ASTReader::ReadASTCore(StringRef FileName,
break;
case ModuleManager::Missing:
- // The module file was missing; if the client handle handle, that, return
+ // The module file was missing; if the client can handle that, return
// it.
if (ClientLoadCapabilities & ARR_Missing)
return Missing;
@@ -8196,14 +8210,16 @@ void ASTReader::finishPendingActions() {
for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
++IDIdx) {
const PendingMacroInfo &Info = GlobalIDs[IDIdx];
- if (Info.M->Kind != MK_Module)
+ if (Info.M->Kind != MK_ImplicitModule &&
+ Info.M->Kind != MK_ExplicitModule)
resolvePendingMacro(II, Info);
}
// Handle module imports.
for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
++IDIdx) {
const PendingMacroInfo &Info = GlobalIDs[IDIdx];
- if (Info.M->Kind == MK_Module)
+ if (Info.M->Kind == MK_ImplicitModule ||
+ Info.M->Kind == MK_ExplicitModule)
resolvePendingMacro(II, Info);
}
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index a3b773f6fc5..b5a447d197d 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1194,7 +1194,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
// any other module's anonymous namespaces, so don't attach the anonymous
// namespace at all.
NamespaceDecl *Anon = ReadDeclAs<NamespaceDecl>(Record, Idx);
- if (F.Kind != MK_Module)
+ if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule)
D->setAnonymousNamespace(Anon);
} else {
// Link this namespace back to the first declaration, which has already
@@ -3536,7 +3536,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
// Each module has its own anonymous namespace, which is disjoint from
// any other module's anonymous namespaces, so don't attach the anonymous
// namespace at all.
- if (ModuleFile.Kind != MK_Module) {
+ if (ModuleFile.Kind != MK_ImplicitModule &&
+ ModuleFile.Kind != MK_ExplicitModule) {
if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
TU->setAnonymousNamespace(Anon);
else
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp
index 18fe035456d..20249e0a7bd 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -89,7 +89,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
ModuleEntry = New;
New->InputFilesValidationTimestamp = 0;
- if (New->Kind == MK_Module) {
+ if (New->Kind == MK_ImplicitModule) {
std::string TimestampFilename = New->getTimestampFilename();
vfs::Status Status;
// A cached stat value would be fine as well.
OpenPOWER on IntegriCloud