summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp111
1 files changed, 67 insertions, 44 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 03ab20b083e..366884ec775 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1257,51 +1257,61 @@ void CompilerInstance::createModuleManager() {
}
}
-ModuleLoadResult
-CompilerInstance::loadModuleFile(StringRef FileName, SourceLocation Loc) {
- if (!ModuleManager)
- createModuleManager();
- if (!ModuleManager)
- return ModuleLoadResult();
+bool CompilerInstance::loadModuleFile(StringRef FileName) {
+ // Helper to recursively read the module names for all modules we're adding.
+ // We mark these as known and redirect any attempt to load that module to
+ // the files we were handed.
+ struct ReadModuleNames : ASTReaderListener {
+ CompilerInstance &CI;
+ std::vector<StringRef> ModuleFileStack;
+ bool Failed;
+ bool TopFileIsModule;
+
+ ReadModuleNames(CompilerInstance &CI)
+ : CI(CI), Failed(false), TopFileIsModule(false) {}
+
+ bool needsImportVisitation() const override { return true; }
+
+ void visitImport(StringRef FileName) override {
+ ModuleFileStack.push_back(FileName);
+ if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
+ *this)) {
+ CI.getDiagnostics().Report(SourceLocation(),
+ diag::err_module_file_not_found)
+ << FileName;
+ // FIXME: Produce a note stack explaining how we got here.
+ Failed = true;
+ }
+ ModuleFileStack.pop_back();
+ }
- // 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();
+ void ReadModuleName(StringRef ModuleName) override {
+ if (ModuleFileStack.size() == 1)
+ TopFileIsModule = true;
- MF = ModuleManager->getModuleManager().lookup(FileName);
- assert(MF && "unexpectedly failed to load module file");
- }
+ auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
+ if (!ModuleFile.empty() && ModuleFile != ModuleFileStack.back())
+ CI.getDiagnostics().Report(SourceLocation(),
+ diag::err_conflicting_module_files)
+ << ModuleName << ModuleFile << ModuleFileStack.back();
+ ModuleFile = ModuleFileStack.back();
+ }
+ } RMN(*this);
+
+ RMN.visitImport(FileName);
- if (MF->ModuleName.empty()) {
- getDiagnostics().Report(Loc, diag::err_module_file_not_module)
+ if (RMN.Failed)
+ return false;
+
+ // If we never found a module name for the top file, then it's not a module,
+ // it's a PCH or preamble or something.
+ if (!RMN.TopFileIsModule) {
+ getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)
<< FileName;
- return ModuleLoadResult();
+ return false;
}
- auto *Module = PP->getHeaderSearchInfo().lookupModule(MF->ModuleName, false);
- return ModuleLoadResult(Module, false);
+
+ return true;
}
ModuleLoadResult
@@ -1349,8 +1359,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
return ModuleLoadResult();
}
+ auto Override = ModuleFileOverrides.find(ModuleName);
+ bool Explicit = Override != ModuleFileOverrides.end();
+
std::string ModuleFileName =
- PP->getHeaderSearchInfo().getModuleFileName(Module);
+ Explicit ? Override->second
+ : PP->getHeaderSearchInfo().getModuleFileName(Module);
// If we don't already have an ASTReader, create one now.
if (!ModuleManager)
@@ -1366,15 +1380,24 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Listener->attachToASTReader(*ModuleManager);
// Try to load the module file.
- unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
+ unsigned ARRFlags =
+ Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
switch (ModuleManager->ReadAST(ModuleFileName,
- serialization::MK_ImplicitModule, ImportLoc,
- ARRFlags)) {
+ Explicit ? serialization::MK_ExplicitModule
+ : serialization::MK_ImplicitModule,
+ ImportLoc, ARRFlags)) {
case ASTReader::Success:
break;
case ASTReader::OutOfDate:
case ASTReader::Missing: {
+ if (Explicit) {
+ // ReadAST has already complained for us.
+ ModuleLoader::HadFatalFailure = true;
+ KnownModules[Path[0].first] = nullptr;
+ return ModuleLoadResult();
+ }
+
// The module file is missing or out-of-date. Build it.
assert(Module && "missing module file");
// Check whether there is a cycle in the module graph.
OpenPOWER on IntegriCloud