[PATCH] D86069: [clang] When loading preamble from AST file, re-export modules in Sema.

2020-08-17 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous.
Herald added a project: clang.
adamcz requested review of this revision.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86069

Files:
  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
  clang/test/PCH/preamble-modules.cpp

Index: clang/test/PCH/preamble-modules.cpp
===
--- /dev/null
+++ 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
Index: clang/test/PCH/Inputs/modules/Foo.h
===
--- clang/test/PCH/Inputs/modules/Foo.h
+++ clang/test/PCH/Inputs/modules/Foo.h
@@ -1 +1,3 @@
 void make_foo(void);
+
+typedef int MyType;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -4987,10 +4987,8 @@
 /*ImportLoc=*/Import.ImportLoc);
   if (Import.ImportLoc.isValid())
 PP.makeModuleVisible(Imported, Import.ImportLoc);
-  // FIXME: should we tell Sema to make the module visible too?
 }
   }
-  ImportedModules.clear();
 }
 
 void ASTReader::finalizeForWriting() {
@@ -7942,6 +7940,15 @@
   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) {
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1912,6 +1912,12 @@
 
   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);
Index: clang-tools-extra/clangd/unittests/ModulesTests.cpp
===
--- clang-tools-extra/clangd/unittests/ModulesTests.cpp
+++ clang-tools-extra/clangd/unittests/ModulesTests.cpp
@@ -26,7 +26,7 @@
 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 @@
   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 

[PATCH] D86069: [clang] When loading preamble from AST file, re-export modules in Sema.

2020-08-18 Thread Sam McCall via Phabricator via cfe-commits
sammccall added inline comments.



Comment at: clang/test/PCH/preamble-modules.cpp:8
+
+#ifndef MAIN_FILE
+#define MAIN_FILE

what are these ifdefs about? you never seem to define this symbol

(Possible you're copying from a test that is doing something tricky like being 
run in two modes or including itself? Or did you mean to give different flags 
for the include vs emit pch?)



Comment at: clang/test/PCH/preamble-modules.cpp:14
+// Main section.
+MyType foo;
+#endif

This seems like currently it's never getting parsed as MAIN_FILE is never 
defined.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86069/new/

https://reviews.llvm.org/D86069

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86069: [clang] When loading preamble from AST file, re-export modules in Sema.

2020-08-18 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added inline comments.



Comment at: clang/test/PCH/preamble-modules.cpp:8
+
+#ifndef MAIN_FILE
+#define MAIN_FILE

sammccall wrote:
> what are these ifdefs about? you never seem to define this symbol
> 
> (Possible you're copying from a test that is doing something tricky like 
> being run in two modes or including itself? Or did you mean to give different 
> flags for the include vs emit pch?)
Oh, I stole this trick from Kadir. You compile this file twice. First one is to 
generate a PCH for preamble. MAIN_FILE is not set, so it only reads the 
preamble section. The second one has -include-pch. That means MAIN_FILE is now 
set (from the preamble PCH file), so we only compile the main section.

It's a creative solution to a problem I wish I didn't have ;-)
Is there a better way to do this, without splitting the file in two? 
preamble_bytes seems fragile.



Comment at: clang/test/PCH/preamble-modules.cpp:14
+// Main section.
+MyType foo;
+#endif

sammccall wrote:
> This seems like currently it's never getting parsed as MAIN_FILE is never 
> defined.
It's parsed. Without this fix, there's a warning generated here. See comment 
above for explanation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86069/new/

https://reviews.llvm.org/D86069

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86069: [clang] When loading preamble from AST file, re-export modules in Sema.

2020-08-19 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added a comment.
This revision is now accepted and ready to land.

Sorry, I was just not reading the test clearly. LGTM




Comment at: clang/lib/Serialization/ASTReader.cpp:4990
 PP.makeModuleVisible(Imported, Import.ImportLoc);
-  // FIXME: should we tell Sema to make the module visible too?
 }

maybe replace this with a comment pointing at UpdateSema() for the sema part


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86069/new/

https://reviews.llvm.org/D86069

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86069: [clang] When loading preamble from AST file, re-export modules in Sema.

2020-08-19 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz updated this revision to Diff 286561.
adamcz added a comment.

Added comment in place of a FIXME


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86069/new/

https://reviews.llvm.org/D86069

Files:
  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
  clang/test/PCH/preamble-modules.cpp

Index: clang/test/PCH/preamble-modules.cpp
===
--- /dev/null
+++ 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
Index: clang/test/PCH/Inputs/modules/Foo.h
===
--- clang/test/PCH/Inputs/modules/Foo.h
+++ clang/test/PCH/Inputs/modules/Foo.h
@@ -1 +1,3 @@
 void make_foo(void);
+
+typedef int MyType;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -4987,10 +4987,10 @@
 /*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() {
@@ -7942,6 +7942,15 @@
   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) {
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1912,6 +1912,12 @@
 
   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);
Index: clang-tools-extra/clangd/unittests/ModulesTests.cpp
===
--- clang-tools-extra/clangd/unittests/ModulesTests.cpp
+++ clang-tools-extra/clangd/unittests/ModulesTests.cpp
@@ -26,7 +26,7 @@
 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 @@
   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
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86069: [clang] When loading preamble from AST file, re-export modules in Sema.

2020-08-20 Thread Adam Czachorowski via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbaeff989b050: [clang] When loading preamble from AST file, 
re-export modules in Sema. (authored by adamcz).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86069/new/

https://reviews.llvm.org/D86069

Files:
  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
  clang/test/PCH/preamble-modules.cpp

Index: clang/test/PCH/preamble-modules.cpp
===
--- /dev/null
+++ 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
Index: clang/test/PCH/Inputs/modules/Foo.h
===
--- clang/test/PCH/Inputs/modules/Foo.h
+++ clang/test/PCH/Inputs/modules/Foo.h
@@ -1 +1,3 @@
 void make_foo(void);
+
+typedef int MyType;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -4987,10 +4987,10 @@
 /*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 @@
   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) {
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1912,6 +1912,12 @@
 
   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);
Index: clang-tools-extra/clangd/unittests/ModulesTests.cpp
===
--- clang-tools-extra/clangd/unittests/ModulesTests.cpp
+++ clang-tools-extra/clangd/unittests/ModulesTests.cpp
@@ -26,7 +26,7 @@
 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 @@
   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
___
cfe-commits mailing list