[clang-tools-extra] baeff98 - [clang] When loading preamble from AST file, re-export modules in Sema.
Adam Czachorowski via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 20 05:33:29 PDT 2020
Author: Adam Czachorowski
Date: 2020-08-20T14:19:52+02:00
New Revision: baeff989b050e0f63412c52c1b8f9d8f3e91f671
URL: https://github.com/llvm/llvm-project/commit/baeff989b050e0f63412c52c1b8f9d8f3e91f671
DIFF: https://github.com/llvm/llvm-project/commit/baeff989b050e0f63412c52c1b8f9d8f3e91f671.diff
LOG: [clang] When loading preamble from AST file, re-export modules in Sema.
This addresses a FIXME in ASTReader.
Modules were already re-exported for Preprocessor, but not for Sema.
The result was that, with -fmodules-local-submodule-visibility, all AST
nodes belonging to a module that was loaded in a premable where not
accesible from the main part of the file and a diagnostic recommending
importing those modules would be generated.
Differential Revision: https://reviews.llvm.org/D86069
Added:
clang/test/PCH/preamble-modules.cpp
Modified:
clang-tools-extra/clangd/unittests/ModulesTests.cpp
clang/include/clang/Sema/Sema.h
clang/lib/Serialization/ASTReader.cpp
clang/test/PCH/Inputs/modules/Foo.h
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/unittests/ModulesTests.cpp b/clang-tools-extra/clangd/unittests/ModulesTests.cpp
index 0098a15f64bb..a10b9e897a48 100644
--- a/clang-tools-extra/clangd/unittests/ModulesTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ModulesTests.cpp
@@ -26,7 +26,7 @@ TEST(Modules, TextualIncludeInPreamble) {
void foo() {}
)cpp");
TU.ExtraArgs.push_back("-fmodule-name=M");
- TU.ExtraArgs.push_back("-fmodule-map-file=m.modulemap");
+ TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
TU.AdditionalFiles["Textual.h"] = "void foo();";
TU.AdditionalFiles["m.modulemap"] = R"modulemap(
module M {
@@ -39,6 +39,31 @@ TEST(Modules, TextualIncludeInPreamble) {
TU.index();
}
+// Verify that visibility of AST nodes belonging to modules, but loaded from
+// preamble PCH, is restored.
+TEST(Modules, PreambleBuildVisibility) {
+ TestTU TU = TestTU::withCode(R"cpp(
+ #include "module.h"
+
+ foo x;
+)cpp");
+ TU.OverlayRealFileSystemForModules = true;
+ TU.ExtraArgs.push_back("-fmodules");
+ TU.ExtraArgs.push_back("-fmodules-strict-decluse");
+ TU.ExtraArgs.push_back("-Xclang");
+ TU.ExtraArgs.push_back("-fmodules-local-submodule-visibility");
+ TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
+ TU.AdditionalFiles["module.h"] = R"cpp(
+ typedef int foo;
+)cpp";
+ TU.AdditionalFiles["m.modulemap"] = R"modulemap(
+ module M {
+ header "module.h"
+ }
+)modulemap";
+ EXPECT_TRUE(TU.build().getDiagnostics().empty());
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 49ab94f9df14..84e66b85208e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1912,6 +1912,12 @@ class Sema final {
bool isModuleVisible(const Module *M, bool ModulePrivate = false);
+ // When loading a non-modular PCH files, this is used to restore module
+ // visibility.
+ void makeModuleVisible(Module *Mod, SourceLocation ImportLoc) {
+ VisibleModules.setVisible(Mod, ImportLoc);
+ }
+
/// Determine whether a declaration is visible to name lookup.
bool isVisible(const NamedDecl *D) {
return D->isUnconditionallyVisible() || isVisibleSlow(D);
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 21cdde9e8455..464bbc662230 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4987,10 +4987,10 @@ void ASTReader::InitializeContext() {
/*ImportLoc=*/Import.ImportLoc);
if (Import.ImportLoc.isValid())
PP.makeModuleVisible(Imported, Import.ImportLoc);
- // FIXME: should we tell Sema to make the module visible too?
+ // This updates visibility for Preprocessor only. For Sema, which can be
+ // nullptr here, we do the same later, in UpdateSema().
}
}
- ImportedModules.clear();
}
void ASTReader::finalizeForWriting() {
@@ -7943,6 +7943,15 @@ void ASTReader::UpdateSema() {
SemaObj->FpPragmaStack.CurrentPragmaLocation = FpPragmaCurrentLocation;
}
}
+
+ // For non-modular AST files, restore visiblity of modules.
+ for (auto &Import : ImportedModules) {
+ if (Import.ImportLoc.isInvalid())
+ continue;
+ if (Module *Imported = getSubmodule(Import.ID)) {
+ SemaObj->makeModuleVisible(Imported, Import.ImportLoc);
+ }
+ }
}
IdentifierInfo *ASTReader::get(StringRef Name) {
diff --git a/clang/test/PCH/Inputs/modules/Foo.h b/clang/test/PCH/Inputs/modules/Foo.h
index d661dbccbc33..c93614e0683f 100644
--- a/clang/test/PCH/Inputs/modules/Foo.h
+++ b/clang/test/PCH/Inputs/modules/Foo.h
@@ -1 +1,3 @@
void make_foo(void);
+
+typedef int MyType;
diff --git a/clang/test/PCH/preamble-modules.cpp b/clang/test/PCH/preamble-modules.cpp
new file mode 100644
index 000000000000..3dff4a4a3287
--- /dev/null
+++ b/clang/test/PCH/preamble-modules.cpp
@@ -0,0 +1,15 @@
+// Check that modules included in the preamble remain visible to the rest of the
+// file.
+
+// RUN: rm -rf %t.mcp
+// RUN: %clang_cc1 -emit-pch -o %t.pch %s -fmodules -fmodule-map-file=%S/Inputs/modules/module.modulemap -fmodules-local-submodule-visibility -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -include-pch %t.pch %s -fmodules -fmodule-map-file=%S/Inputs/modules/module.modulemap -fmodules-local-submodule-visibility -fmodules-cache-path=%t.mcp
+
+#ifndef MAIN_FILE
+#define MAIN_FILE
+// Premable section.
+#include "Inputs/modules/Foo.h"
+#else
+// Main section.
+MyType foo;
+#endif
More information about the cfe-commits
mailing list