diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -686,6 +686,8 @@ /// creating modules. /// \param Diags - The diagnostics engine to use for reporting errors; its /// lifetime is expected to extend past that of the returned ASTUnit. + /// \param PrebuiltModuleFiles - A map for module names to prebuilt module + /// paths. /// /// \returns - The initialized ASTUnit or null if the AST failed to load. static std::unique_ptr LoadFromASTFile( @@ -695,7 +697,8 @@ bool OnlyLocalDecls = false, ArrayRef RemappedFiles = None, CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, bool AllowPCHWithCompilerErrors = false, - bool UserFilesAreVolatile = false); + bool UserFilesAreVolatile = false, + const std::map &PrebuiltModuleFiles = {}); private: /// Helper function for \c LoadFromCompilerInvocation() and diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -759,7 +759,8 @@ const FileSystemOptions &FileSystemOpts, bool UseDebugInfo, bool OnlyLocalDecls, ArrayRef RemappedFiles, CaptureDiagsKind CaptureDiagnostics, bool AllowPCHWithCompilerErrors, - bool UserFilesAreVolatile) { + bool UserFilesAreVolatile, + const std::map &PrebuiltModuleFiles) { std::unique_ptr AST(new ASTUnit(true)); // Recover resources if we crash before exiting this method. @@ -785,6 +786,7 @@ AST->ModuleCache = new InMemoryModuleCache; AST->HSOpts = std::make_shared(); AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat(); + AST->HSOpts->PrebuiltModuleFiles = PrebuiltModuleFiles; AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, AST->getSourceManager(), AST->getDiagnostics(), diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -565,7 +565,9 @@ std::unique_ptr AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), ASTUnit::LoadPreprocessorOnly, - ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); + ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs, + false, None, CaptureDiagsKind::None, false, false, + CI.getHeaderSearchOpts().PrebuiltModuleFiles); if (!AST) goto failure; @@ -631,7 +633,9 @@ std::unique_ptr AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags, - CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); + CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs, false, + None, CaptureDiagsKind::None, false, false, + CI.getHeaderSearchOpts().PrebuiltModuleFiles); if (!AST) goto failure; diff --git a/clang/test/Modules/Inputs/explicit-build-pcm/a.h b/clang/test/Modules/Inputs/explicit-build-pcm/a.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/explicit-build-pcm/a.h @@ -0,0 +1,5 @@ +#if !__building_module(a) && !BUILDING_A_PCH +#error "should only get here when building module a" +#endif + +const int a = 1; diff --git a/clang/test/Modules/Inputs/explicit-build-pcm/b.h b/clang/test/Modules/Inputs/explicit-build-pcm/b.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/explicit-build-pcm/b.h @@ -0,0 +1,7 @@ +#include "a.h" + +#if !__building_module(b) +#error "should only get here when building module b" +#endif + +const int b = 2; diff --git a/clang/test/Modules/Inputs/explicit-build-pcm/c.h b/clang/test/Modules/Inputs/explicit-build-pcm/c.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/explicit-build-pcm/c.h @@ -0,0 +1,7 @@ +#include "b.h" + +#if !__building_module(c) +#error "should only get here when building module c" +#endif + +const int c = 3; diff --git a/clang/test/Modules/Inputs/explicit-build-pcm/d.h b/clang/test/Modules/Inputs/explicit-build-pcm/d.h new file mode 100644 diff --git a/clang/test/Modules/Inputs/explicit-build-pcm/module.modulemap b/clang/test/Modules/Inputs/explicit-build-pcm/module.modulemap new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/explicit-build-pcm/module.modulemap @@ -0,0 +1,4 @@ +module a { header "a.h" } +module b { header "b.h" export * } +module c { header "c.h" export * } +module d { header "d.h" } diff --git a/clang/test/Modules/explicit-build-pcm.cpp b/clang/test/Modules/explicit-build-pcm.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Modules/explicit-build-pcm.cpp @@ -0,0 +1,26 @@ +// RUN: rm -rf %t +// expected-no-diagnostics + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \ +// RUN: -fmodule-name=a -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/a.pcm + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \ +// RUN: -fmodule-file=a=%t/a.pcm \ +// RUN: -fmodule-name=b -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/b.pcm + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \ +// RUN: -fmodule-file=a=%t/a.pcm \ +// RUN: -fmodule-file=b=%t/b.pcm \ +// RUN: -fmodule-name=c -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/c.pcm + +// RUN: mv %t/a.pcm %t/a.moved.pcm +// RUN: mv %t/b.pcm %t/b.moved.pcm +// RUN: mv %t/c.pcm %t/c.moved.pcm +// +// RUN: %clang_cc1 -x pcm -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \ +// RUN: -fmodule-file=a=%t/a.moved.pcm \ +// RUN: -fmodule-file=b=%t/b.moved.pcm \ +// RUN: %t/c.moved.pcm -o %t/c.o +// expected-no-diagnostics + +#include