diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-22 02:05:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-22 02:05:46 +0000 |
commit | e842a47452223f9f3b683e0f7f9cccb48192cbb6 (patch) | |
tree | d86e1e37d64cc2aa392947392af816d5b79583ad /clang/lib/Frontend/CompilerInstance.cpp | |
parent | a672ecefef25bcc8cf0d7ac8d54c5139f6386df4 (diff) | |
download | bcm5719-llvm-e842a47452223f9f3b683e0f7f9cccb48192cbb6.tar.gz bcm5719-llvm-e842a47452223f9f3b683e0f7f9cccb48192cbb6.zip |
[modules] Initial support for explicitly loading .pcm files.
Implicit module builds are not well-suited to a lot of build systems. In
particular, they fare badly in distributed build systems, and they lead to
build artifacts that are not tracked as part of the usual dependency management
process. This change allows explicitly-built module files (which are already
supported through the -emit-module flag) to be explicitly loaded into a build,
allowing build systems to opt to manage module builds and dependencies
themselves.
This is only the first step in supporting such configurations, and it should
be considered experimental and subject to change or removal for now.
llvm-svn: 220359
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 54 |
1 files changed, 51 insertions, 3 deletions
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; |