forked from OSchip/llvm-project
[modules] When we #include a local submodule header that we've already built,
and it has an include guard, produce callbacks for a module import, not for a skipped non-modular header. Fixes -E output when preprocessing a module to list these cases as a module import, rather than suppressing the #include and losing the import side effect. llvm-svn: 304183
This commit is contained in:
parent
1da971706e
commit
c5247e67e8
|
@ -1906,6 +1906,25 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
}
|
||||
}
|
||||
|
||||
// The #included file will be considered to be a system header if either it is
|
||||
// in a system include directory, or if the #includer is a system include
|
||||
// header.
|
||||
SrcMgr::CharacteristicKind FileCharacter =
|
||||
SourceMgr.getFileCharacteristic(FilenameTok.getLocation());
|
||||
if (File)
|
||||
FileCharacter = std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter);
|
||||
|
||||
// Ask HeaderInfo if we should enter this #include file. If not, #including
|
||||
// this file will have no effect.
|
||||
bool SkipHeader = false;
|
||||
if (ShouldEnter && File &&
|
||||
!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
|
||||
getLangOpts().Modules,
|
||||
SuggestedModule.getModule())) {
|
||||
ShouldEnter = false;
|
||||
SkipHeader = true;
|
||||
}
|
||||
|
||||
if (Callbacks) {
|
||||
// Notify the callback object that we've seen an inclusion directive.
|
||||
Callbacks->InclusionDirective(
|
||||
|
@ -1913,18 +1932,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
|
||||
FilenameRange, File, SearchPath, RelativePath,
|
||||
ShouldEnter ? nullptr : SuggestedModule.getModule());
|
||||
if (SkipHeader && !SuggestedModule.getModule())
|
||||
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
|
||||
}
|
||||
|
||||
if (!File)
|
||||
return;
|
||||
|
||||
// The #included file will be considered to be a system header if either it is
|
||||
// in a system include directory, or if the #includer is a system include
|
||||
// header.
|
||||
SrcMgr::CharacteristicKind FileCharacter =
|
||||
std::max(HeaderInfo.getFileDirFlavor(File),
|
||||
SourceMgr.getFileCharacteristic(FilenameTok.getLocation()));
|
||||
|
||||
// FIXME: If we have a suggested module, and we've already visited this file,
|
||||
// don't bother entering it again. We know it has no further effect.
|
||||
|
||||
|
@ -1964,19 +1978,6 @@ 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,
|
||||
getLangOpts().Modules,
|
||||
SuggestedModule.getModule())) {
|
||||
ShouldEnter = false;
|
||||
SkipHeader = true;
|
||||
if (Callbacks)
|
||||
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
|
||||
}
|
||||
|
||||
// If we don't need to enter the file, stop now.
|
||||
if (!ShouldEnter) {
|
||||
// If this is a module import, make it visible if needed.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#include "c.h"
|
||||
T a();
|
|
@ -0,0 +1,2 @@
|
|||
#include "c.h"
|
||||
T b();
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef C_H
|
||||
#define C_H
|
||||
using T = int;
|
||||
#endif
|
|
@ -1,2 +1,7 @@
|
|||
module fwd { header "fwd.h" export * }
|
||||
module file { header "file.h" header "file2.h" export * }
|
||||
module nested {
|
||||
module a { header "a.h" }
|
||||
module b { header "b.h" }
|
||||
module c { header "c.h" }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: mkdir %t
|
||||
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fmodule-name=nested -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -E -o %t/no-rewrite.ii
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fmodule-name=nested -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -E -frewrite-includes -o %t/rewrite.ii
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/no-rewrite.ii --check-prefix=CHECK --check-prefix=NO-REWRITE
|
||||
// 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
|
||||
|
||||
// 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
|
||||
|
||||
// == module map
|
||||
// CHECK: # 1 "{{.*}}module.modulemap"
|
||||
// CHECK: module nested {
|
||||
// CHECK: module a {
|
||||
// CHECK: header "a.h"
|
||||
// CHECK: }
|
||||
// CHECK: module b {
|
||||
// CHECK: header "b.h"
|
||||
// CHECK: }
|
||||
// CHECK: module c {
|
||||
// CHECK: header "c.h"
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: #pragma clang module begin nested.a
|
||||
// CHECK: #pragma clang module begin nested.c
|
||||
// CHECK: using T = int;
|
||||
// CHECK: #pragma clang module end
|
||||
// CHECK: T a();
|
||||
// CHECK: #pragma clang module end
|
||||
|
||||
// CHECK: #pragma clang module begin nested.b
|
||||
// CHECK: #pragma clang module import nested.c
|
||||
// CHECK-NOT: #pragma clang module begin nested.c
|
||||
// CHECK-NOT: using T = int;
|
||||
// CHECK-NOT: #pragma clang module end
|
||||
// CHECK: T b();
|
||||
// CHECK: #pragma clang module end
|
||||
|
||||
// CHECK: #pragma clang module import nested.c
|
||||
|
||||
#pragma clang module import nested.b
|
||||
|
||||
int n = b();
|
||||
T c; // expected-error {{must be imported}}
|
||||
#ifdef REWRITE
|
||||
// expected-note@rewrite.ii:* {{declar}}
|
||||
#else
|
||||
// expected-note@no-rewrite.ii:* {{declar}}
|
||||
#endif
|
Loading…
Reference in New Issue