forked from OSchip/llvm-project
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 llvm-svn: 291465
This commit is contained in:
parent
87495eb8ef
commit
ffd3e9d766
|
@ -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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
// in pch
|
|
@ -0,0 +1 @@
|
|||
#include "D.h"
|
|
@ -0,0 +1 @@
|
|||
//empty
|
|
@ -0,0 +1 @@
|
|||
//empty
|
|
@ -0,0 +1,9 @@
|
|||
module CloudKit {
|
||||
header "C.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module Contacts {
|
||||
header "D.h"
|
||||
export *
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#include "A.h"
|
|
@ -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"
|
Loading…
Reference in New Issue