summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Frontend')
-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
4 files changed, 67 insertions, 6 deletions
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() &&
OpenPOWER on IntegriCloud