diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSerializationKinds.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Serialization/Module.h | 3 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 7 |
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; } |