summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSerializationKinds.td2
-rw-r--r--clang/include/clang/Serialization/Module.h3
-rw-r--r--clang/lib/Serialization/ASTReader.cpp7
3 files changed, 12 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 757dbbeee3c..f499996470c 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -74,6 +74,8 @@ def note_module_file_imported_by : Note<
"imported by %select{|module '%2' in }1'%0'">;
def err_module_file_not_module : Error<
"AST file '%0' was not built as a module">, DefaultFatal;
+def err_module_file_missing_top_level_submodule : Error<
+ "module file '%0' is missing its top-level submodule">, DefaultFatal;
def remark_module_import : Remark<
"importing module '%0'%select{| into '%3'}2 from '%1'">,
diff --git a/clang/include/clang/Serialization/Module.h b/clang/include/clang/Serialization/Module.h
index 1979c53a713..b5afdf90c6a 100644
--- a/clang/include/clang/Serialization/Module.h
+++ b/clang/include/clang/Serialization/Module.h
@@ -159,6 +159,9 @@ public:
/// Whether the PCH has a corresponding object file.
bool PCHHasObjectFile = false;
+ /// Whether the top-level module has been read from the AST file.
+ bool DidReadTopLevelSubmodule = false;
+
/// The file entry for the module file.
const FileEntry *File = nullptr;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f7e3805fd04..9111b60a717 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4217,6 +4217,12 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
if (ASTReadResult Result = ReadASTBlock(F, ClientLoadCapabilities))
return removeModulesAndReturn(Result);
+ // The AST block should always have a definition for the main module.
+ if (F.isModule() && !F.DidReadTopLevelSubmodule) {
+ Error(diag::err_module_file_missing_top_level_submodule, F.FileName);
+ return removeModulesAndReturn(Failure);
+ }
+
// Read the extension blocks.
while (!SkipCursorToBlock(F.Stream, EXTENSION_BLOCK_ID)) {
if (ASTReadResult Result = ReadExtensionBlock(F))
@@ -5489,6 +5495,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
}
}
+ F.DidReadTopLevelSubmodule = true;
CurrentModule->setASTFile(F.File);
CurrentModule->PresumedModuleMapFile = F.ModuleMapPath;
}
OpenPOWER on IntegriCloud