summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Lex/PPDirectives.cpp41
-rw-r--r--clang/test/Modules/Inputs/preprocess/a.h2
-rw-r--r--clang/test/Modules/Inputs/preprocess/b.h2
-rw-r--r--clang/test/Modules/Inputs/preprocess/c.h4
-rw-r--r--clang/test/Modules/Inputs/preprocess/module.modulemap5
-rw-r--r--clang/test/Modules/preprocess-nested.cpp59
6 files changed, 93 insertions, 20 deletions
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 030717b8bd5..8b5877934f6 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -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.
diff --git a/clang/test/Modules/Inputs/preprocess/a.h b/clang/test/Modules/Inputs/preprocess/a.h
new file mode 100644
index 00000000000..1292e99b4b2
--- /dev/null
+++ b/clang/test/Modules/Inputs/preprocess/a.h
@@ -0,0 +1,2 @@
+#include "c.h"
+T a();
diff --git a/clang/test/Modules/Inputs/preprocess/b.h b/clang/test/Modules/Inputs/preprocess/b.h
new file mode 100644
index 00000000000..e8a9f55968f
--- /dev/null
+++ b/clang/test/Modules/Inputs/preprocess/b.h
@@ -0,0 +1,2 @@
+#include "c.h"
+T b();
diff --git a/clang/test/Modules/Inputs/preprocess/c.h b/clang/test/Modules/Inputs/preprocess/c.h
new file mode 100644
index 00000000000..718f5dc1829
--- /dev/null
+++ b/clang/test/Modules/Inputs/preprocess/c.h
@@ -0,0 +1,4 @@
+#ifndef C_H
+#define C_H
+using T = int;
+#endif
diff --git a/clang/test/Modules/Inputs/preprocess/module.modulemap b/clang/test/Modules/Inputs/preprocess/module.modulemap
index 943435a953d..f700db03bea 100644
--- a/clang/test/Modules/Inputs/preprocess/module.modulemap
+++ b/clang/test/Modules/Inputs/preprocess/module.modulemap
@@ -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" }
+}
diff --git a/clang/test/Modules/preprocess-nested.cpp b/clang/test/Modules/preprocess-nested.cpp
new file mode 100644
index 00000000000..8fccf137e94
--- /dev/null
+++ b/clang/test/Modules/preprocess-nested.cpp
@@ -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
OpenPOWER on IntegriCloud