summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2017-01-09 19:20:18 +0000
committerManman Ren <manman.ren@gmail.com>2017-01-09 19:20:18 +0000
commitda676ade4fbf9084d0cb3ddea8a51dd69802f778 (patch)
tree7ae90d518ae5968c49685b45c87fb6958c6a4396
parentc24cbe958c6e8b418d0f767abfe702cf7035bcf8 (diff)
PCH: fix a regression that reports a module is defined in both pch and pcm.
In r276159, we started to say that a module X is defined in a pch if we specify -fmodule-name when building the pch. This caused a regression that reports module X is defined in both pch and pcm if we generate the pch with -fmodule-name=X and then in a separate clang invocation, we include the pch and also import X.pcm. This patch adds an option CompilingPCH similar to CompilingModule. When we use -fmodule-name=X while building a pch, modular headers in X will be textually included and the compiler knows that we are not building module X, so we don't put module X in SUBMODULE_DEFINITION of the pch. Differential Revision: http://reviews.llvm.org/D28415 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291465 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/LangOptions.def1
-rw-r--r--include/clang/Frontend/FrontendActions.h2
-rw-r--r--lib/Frontend/FrontendActions.cpp6
-rw-r--r--lib/Lex/PPDirectives.cpp17
-rw-r--r--lib/Serialization/ASTWriter.cpp11
-rw-r--r--test/Modules/Inputs/pch-with-module-name/A.h1
-rw-r--r--test/Modules/Inputs/pch-with-module-name/C.h1
-rw-r--r--test/Modules/Inputs/pch-with-module-name/C.m1
-rw-r--r--test/Modules/Inputs/pch-with-module-name/D.h1
-rw-r--r--test/Modules/Inputs/pch-with-module-name/module.modulemap9
-rw-r--r--test/Modules/Inputs/pch-with-module-name/test.h1
-rw-r--r--test/Modules/pch-with-module-name.m5
12 files changed, 45 insertions, 11 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 47db50c52b..d944a9d78a 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -146,6 +146,7 @@ LANGOPT(Modules , 1, 0, "modules extension to C")
COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS")
BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
"compiling a module interface")
+BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index a073ca5bfd..20fddc4d5a 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -88,6 +88,8 @@ public:
static std::unique_ptr<raw_pwrite_stream>
ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
std::string &Sysroot, std::string &OutputFile);
+
+ bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
};
class GenerateModuleAction : public ASTFrontendAction {
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index eb91940cbb..f795a1d047 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -127,6 +127,12 @@ GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
return OS;
}
+bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) {
+ CI.getLangOpts().CompilingPCH = true;
+ return true;
+}
+
std::unique_ptr<ASTConsumer>
GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 85504de3d1..9661e7b13f 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1996,10 +1996,12 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Ask HeaderInfo if we should enter this #include file. If not, #including
// this file will have no effect.
+ bool SkipHeader = false;
if (ShouldEnter &&
!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
SuggestedModule.getModule())) {
ShouldEnter = false;
+ SkipHeader = true;
if (Callbacks)
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
}
@@ -2008,6 +2010,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
if (!ShouldEnter) {
// If this is a module import, make it visible if needed.
if (auto *M = SuggestedModule.getModule()) {
+ // When building a pch, -fmodule-name tells the compiler to textually
+ // include headers in the specified module. But it is possible that
+ // ShouldEnter is false because we are skipping the header. In that
+ // case, We are not importing the specified module.
+ if (SkipHeader && getLangOpts().CompilingPCH &&
+ M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ return;
+
makeModuleVisible(M, HashLoc);
if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
@@ -2032,6 +2042,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Determine if we're switching to building a new submodule, and which one.
if (auto *M = SuggestedModule.getModule()) {
+ // When building a pch, -fmodule-name tells the compiler to textually
+ // include headers in the specified module. We are not building the
+ // specified module.
+ if (getLangOpts().CompilingPCH &&
+ M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ return;
+
assert(!CurSubmodule && "should not have marked this as a module yet");
CurSubmodule = M;
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 2a5eda436f..39e842db2b 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -4654,17 +4654,6 @@ uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// If we're emitting a module, write out the submodule information.
if (WritingModule)
WriteSubmodules(WritingModule);
- else if (!getLangOpts().CurrentModule.empty()) {
- // If we're building a PCH in the implementation of a module, we may need
- // the description of the current module.
- //
- // FIXME: We may need other modules that we did not load from an AST file,
- // such as if a module declares a 'conflicts' on a different module.
- Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(
- getLangOpts().CurrentModule);
- if (M && !M->IsFromModuleFile)
- WriteSubmodules(M);
- }
Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
diff --git a/test/Modules/Inputs/pch-with-module-name/A.h b/test/Modules/Inputs/pch-with-module-name/A.h
new file mode 100644
index 0000000000..a73b3759d4
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/A.h
@@ -0,0 +1 @@
+// in pch
diff --git a/test/Modules/Inputs/pch-with-module-name/C.h b/test/Modules/Inputs/pch-with-module-name/C.h
new file mode 100644
index 0000000000..f681dd8097
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/C.h
@@ -0,0 +1 @@
+#include "D.h"
diff --git a/test/Modules/Inputs/pch-with-module-name/C.m b/test/Modules/Inputs/pch-with-module-name/C.m
new file mode 100644
index 0000000000..90fe1bcc58
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/C.m
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/pch-with-module-name/D.h b/test/Modules/Inputs/pch-with-module-name/D.h
new file mode 100644
index 0000000000..90fe1bcc58
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/D.h
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/pch-with-module-name/module.modulemap b/test/Modules/Inputs/pch-with-module-name/module.modulemap
new file mode 100644
index 0000000000..379b0d48d5
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/module.modulemap
@@ -0,0 +1,9 @@
+module CloudKit {
+ header "C.h"
+ export *
+}
+
+module Contacts {
+ header "D.h"
+ export *
+}
diff --git a/test/Modules/Inputs/pch-with-module-name/test.h b/test/Modules/Inputs/pch-with-module-name/test.h
new file mode 100644
index 0000000000..7a13ba4d72
--- /dev/null
+++ b/test/Modules/Inputs/pch-with-module-name/test.h
@@ -0,0 +1 @@
+#include "A.h"
diff --git a/test/Modules/pch-with-module-name.m b/test/Modules/pch-with-module-name.m
new file mode 100644
index 0000000000..c4096308c4
--- /dev/null
+++ b/test/Modules/pch-with-module-name.m
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/pch-with-module-name -emit-pch -o %t-A.pch %S/Inputs/pch-with-module-name/test.h -fmodule-name=Contacts -x objective-c-header
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/pch-with-module-name -include-pch %t-A.pch %s -fsyntax-only -fmodule-name=Contacts -verify
+// expected-no-diagnostics
+#include "C.h"