diff options
-rw-r--r-- | clang/include/clang/Basic/Module.h | 4 | ||||
-rw-r--r-- | clang/include/clang/Lex/HeaderSearch.h | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Lex/HeaderSearch.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 9 | ||||
-rw-r--r-- | clang/test/Modules/preprocess-module.cpp | 10 | ||||
-rw-r--r-- | clang/test/Modules/preprocess-nested.cpp | 2 |
7 files changed, 48 insertions, 21 deletions
diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 28aa7db5299..326d84eeb6c 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -83,6 +83,10 @@ public: /// are found. const DirectoryEntry *Directory; + /// \brief The presumed file name for the module map defining this module. + /// Only non-empty when building from preprocessed source. + std::string PresumedModuleMapFile; + /// \brief The umbrella header or directory. llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella; diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 6e24e1893ab..ee17dcbb8b5 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -543,10 +543,13 @@ public: /// \param Offset [inout] An offset within ID to start parsing. On exit, /// filled by the end of the parsed contents (either EOF or the /// location of an end-of-module-map pragma). - /// + /// \param OriginalModuleMapFile The original path to the module map file, + /// used to resolve paths within the module (this is required when + /// building the module from preprocessed source). /// \returns true if an error occurred, false otherwise. bool loadModuleMapFile(const FileEntry *File, bool IsSystem, - FileID ID = FileID(), unsigned *Offset = nullptr); + FileID ID = FileID(), unsigned *Offset = nullptr, + StringRef OriginalModuleMapFile = StringRef()); /// \brief Collect the set of all known, top-level modules. /// diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 874c1b6be41..cd67e469dda 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -373,10 +373,11 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, return std::error_code(); } -static bool -loadModuleMapForModuleBuild(CompilerInstance &CI, StringRef Filename, - bool IsSystem, bool IsPreprocessed, - unsigned &Offset) { +static bool loadModuleMapForModuleBuild(CompilerInstance &CI, + StringRef Filename, bool IsSystem, + bool IsPreprocessed, + std::string &PresumedModuleMapFile, + unsigned &Offset) { auto &SrcMgr = CI.getSourceManager(); HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo(); @@ -388,16 +389,15 @@ loadModuleMapForModuleBuild(CompilerInstance &CI, StringRef Filename, // line directives are not part of the module map syntax in general. Offset = 0; if (IsPreprocessed) { - std::string PresumedModuleMapFile; SourceLocation EndOfLineMarker = ReadOriginalFileName(CI, PresumedModuleMapFile, /*AddLineNote*/true); if (EndOfLineMarker.isValid()) Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second; - // FIXME: Use PresumedModuleMapFile as the MODULE_MAP_FILE in the PCM. } // Load the module map file. - if (HS.loadModuleMapFile(ModuleMap, IsSystem, ModuleMapID, &Offset)) + if (HS.loadModuleMapFile(ModuleMap, IsSystem, ModuleMapID, &Offset, + PresumedModuleMapFile)) return true; if (SrcMgr.getBuffer(ModuleMapID)->getBufferSize() == Offset) @@ -664,15 +664,19 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (Input.getKind().getFormat() == InputKind::ModuleMap) { CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap); + std::string PresumedModuleMapFile; unsigned OffsetToContents; if (loadModuleMapForModuleBuild(CI, Input.getFile(), Input.isSystem(), - Input.isPreprocessed(), OffsetToContents)) + Input.isPreprocessed(), + PresumedModuleMapFile, OffsetToContents)) goto failure; auto *CurrentModule = prepareToBuildModule(CI, Input.getFile()); if (!CurrentModule) goto failure; + CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile; + if (OffsetToContents) // If the module contents are in the same file, skip to them. CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true); diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index f5b7c59e446..9084bc352f7 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -1326,14 +1326,27 @@ static const FileEntry *getPrivateModuleMap(const FileEntry *File, } bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem, - FileID ID, unsigned *Offset) { + FileID ID, unsigned *Offset, + StringRef OriginalModuleMapFile) { // Find the directory for the module. For frameworks, that may require going // up from the 'Modules' directory. const DirectoryEntry *Dir = nullptr; if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) Dir = FileMgr.getDirectory("."); else { - Dir = File->getDir(); + if (!OriginalModuleMapFile.empty()) { + // We're building a preprocessed module map. Find or invent the directory + // that it originally occupied. + Dir = FileMgr.getDirectory( + llvm::sys::path::parent_path(OriginalModuleMapFile)); + if (!Dir) { + auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0); + Dir = FakeFile->getDir(); + } + } else { + Dir = File->getDir(); + } + StringRef DirName(Dir->getName()); if (llvm::sys::path::filename(DirName) == "Modules") { DirName = llvm::sys::path::parent_path(DirName); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index c931b13f65f..95cb54f944e 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1422,8 +1422,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record, getClangFullRepositoryVersion()); } - if (WritingModule) { + if (WritingModule) { // Module name auto Abbrev = std::make_shared<BitCodeAbbrev>(); Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME)); @@ -1466,9 +1466,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Record.clear(); auto &Map = PP.getHeaderSearchInfo().getModuleMap(); - - // Primary module map file. - AddPath(Map.getModuleMapFileForUniquing(WritingModule)->getName(), Record); + AddPath(WritingModule->PresumedModuleMapFile.empty() + ? Map.getModuleMapFileForUniquing(WritingModule)->getName() + : StringRef(WritingModule->PresumedModuleMapFile), + Record); // Additional module map files. if (auto *AdditionalModMaps = diff --git a/clang/test/Modules/preprocess-module.cpp b/clang/test/Modules/preprocess-module.cpp index eaab3136938..9d1a2bb6801 100644 --- a/clang/test/Modules/preprocess-module.cpp +++ b/clang/test/Modules/preprocess-module.cpp @@ -14,8 +14,6 @@ // RUN: FileCheck %s --input-file %t/rewrite.ii --check-prefix=CHECK --check-prefix=REWRITE // Check that we can build a module from the preprocessed output. -// FIXME: For now, we need the headers to exist. -// RUN: touch %t/file.h %t/file2.h // RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/no-rewrite.ii -emit-module -o %t/no-rewrite.pcm // RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/rewrite.ii -emit-module -o %t/rewrite.pcm @@ -27,6 +25,8 @@ // Check the module we built works. // RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -I%t -verify -fno-modules-error-recovery // RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DREWRITE +// RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DINCLUDE -I%S/Inputs/preprocess +// RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DREWRITE -DINCLUDE -I%S/Inputs/preprocess // == module map @@ -102,7 +102,11 @@ __FILE *a; // expected-error {{declaration of '__FILE' must be imported}} // expected-note@no-rewrite.ii:1 {{here}} #endif +#ifdef INCLUDE +#include "file.h" +#else #pragma clang module import file +#endif FILE *b; -int x = file2; +int x = file2; // ok, found in file2.h, even under -DINCLUDE diff --git a/clang/test/Modules/preprocess-nested.cpp b/clang/test/Modules/preprocess-nested.cpp index 8fccf137e94..f26b65507ec 100644 --- a/clang/test/Modules/preprocess-nested.cpp +++ b/clang/test/Modules/preprocess-nested.cpp @@ -8,8 +8,6 @@ // RUN: FileCheck %s --input-file %t/rewrite.ii --check-prefix=CHECK --check-prefix=REWRITE // Check that we can build a module from the preprocessed output. -// FIXME: For now, the files need to exist. -// RUN: touch %t/a.h %t/b.h %t/c.h // RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fmodule-name=nested -x c++-module-map-cpp-output %t/no-rewrite.ii -emit-module -o %t/no-rewrite.pcm // RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fmodule-name=nested -x c++-module-map-cpp-output %t/rewrite.ii -emit-module -o %t/rewrite.pcm |