summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Module.h4
-rw-r--r--clang/include/clang/Lex/HeaderSearch.h7
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp20
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp17
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp9
-rw-r--r--clang/test/Modules/preprocess-module.cpp10
-rw-r--r--clang/test/Modules/preprocess-nested.cpp2
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
OpenPOWER on IntegriCloud