Skip to content

[clang][include-tree] Load even spurious modular dependencies #8011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 8, 2024

Conversation

jansvoboda11
Copy link

@jansvoboda11 jansvoboda11 commented Jan 22, 2024

With implicit modules, some modular dependencies can be "spurious". By that I mean that #include "Header.h" results in a PCM file load, but the header ends up being included textually anyways. (This can happen in situations that would trigger the -Wincomplete-umbrella warning.)

This patch ensures this behavior is preserved with include-tree. Previously, include-tree would simply textually include the header file and skip the PCM file load. This now ensures consistent behavior in edge-cases like the one in the attached test case (with -fmodule-name=X).

rdar://121220983

@jansvoboda11
Copy link
Author

Pushed new commit that approaches the fix from different angle. It introduces new include-tree node that attempts to mimic what happens in implicit builds and non-caching explicit builds: Spurious.pcm is loaded, the Missing submodule is found to be missing, and the header is included textually instead. Loading Spurious.pcm also loads Mod.pcm, so importing Mod for visibility only has the desired effect of making its symbols visible.

Copy link

@benlangmuir benlangmuir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we upstream the PPCallbacks change. Relatedly, should anywhere you have if (SuggestedModule && ModuleImported) be simplified to if (ModuleImported) ? It seems like SuggestedModule should never be null if we're importing it, right?

@jansvoboda11
Copy link
Author

I suggest we upstream the PPCallbacks change.

Yes, if this approach gets a green light, I'll upstream this change.

Relatedly, should anywhere you have if (SuggestedModule && ModuleImported) be simplified to if (ModuleImported) ? It seems like SuggestedModule should never be null if we're importing it, right?

That's correct. I'll update any current uses of SuggestedModule && ModuleImported.

@jansvoboda11
Copy link
Author

Sorry, I should've mentioned this is more of a proof-of-concept that I wanted to get some high-level feedback on. I'm happy to implement the TODO and deal with errors properly if we agree this approach makes sense.

@jansvoboda11 jansvoboda11 force-pushed the jan_svoboda/module-implementation-caching branch from 3b2e935 to ed3e1e7 Compare February 7, 2024 22:40
@jansvoboda11 jansvoboda11 changed the title [clang][deps] Ensure include-tree loads implementation module when necessary [clang][include-tree] Load even spurious modular dependencies Feb 7, 2024
Copy link

@benlangmuir benlangmuir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a couple of small suggestions

if (auto *Import = std::get_if<PPCachedActions::IncludeModule>(&Include)) {
};

auto LoadModule = [&](const PPCachedActions::IncludeModule *Import) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe factor HandleIncludeMod to call LoadModule and make the diagnostic part conditional? The error-handling logic is sufficiently interesting to not want it repeated.

// RUN: FileCheck %s -input-file %t/tu-include-tree.txt -DPREFIX=%/t
// CHECK: [[PREFIX]]/tu.m llvmcas://
// CHECK-NEXT: 1:1 <built-in> llvmcas://
// CHECK-NEXT: 2:1 (Module) Spurious.Missing [[PREFIX]]/frameworks/Spurious.framework/Headers/Missing.h llvmcas://

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we should mark this as a spurious import explicitly in the output for readability. Either inline or you could split it across lines and indent the import + tree.

jansvoboda11 added a commit to llvm/llvm-project that referenced this pull request Feb 8, 2024
…allback (#81061)

This patch provides more information to the
`PPCallbacks::InclusionDirective()` hook. We now always pass the
suggested module, regardless of whether it was actually imported or not.
The extra `bool ModuleImported` parameter then denotes whether the
header `#include` will be automatically translated into import the the
module.

The main change is in `clang/lib/Lex/PPDirectives.cpp`, where we take
care to not modify `SuggestedModule` after it's been populated by
`LookupHeaderIncludeOrImport()`. We now exclusively use the `SM`
(`ModuleToImport`) variable instead, which has been equivalent to
`SuggestedModule` until now. This allows us to use the original
non-modified `SuggestedModule` for the callback itself.

(This patch turns out to be necessary for
swiftlang#8011).
@jansvoboda11 jansvoboda11 force-pushed the jan_svoboda/module-implementation-caching branch from cd70936 to a3fdbdc Compare February 8, 2024 21:01
@jansvoboda11 jansvoboda11 merged commit b230339 into next Feb 8, 2024
@jansvoboda11 jansvoboda11 deleted the jan_svoboda/module-implementation-caching branch February 8, 2024 21:01
jansvoboda11 added a commit that referenced this pull request Feb 8, 2024
…allback (llvm#81061)

This patch provides more information to the
`PPCallbacks::InclusionDirective()` hook. We now always pass the
suggested module, regardless of whether it was actually imported or not.
The extra `bool ModuleImported` parameter then denotes whether the
header `#include` will be automatically translated into import the the
module.

The main change is in `clang/lib/Lex/PPDirectives.cpp`, where we take
care to not modify `SuggestedModule` after it's been populated by
`LookupHeaderIncludeOrImport()`. We now exclusively use the `SM`
(`ModuleToImport`) variable instead, which has been equivalent to
`SuggestedModule` until now. This allows us to use the original
non-modified `SuggestedModule` for the callback itself.

(This patch turns out to be necessary for
#8011).

(cherry picked from commit da95d92)
jansvoboda11 added a commit that referenced this pull request Feb 8, 2024
With implicit modules, some modular dependencies can be "spurious". By that I mean that `#include "Header.h"` results in a PCM file load, but the header ends up being included textually anyways. (This can happen in situations that would trigger the `-Wincomplete-umbrella` warning.)

This patch ensures this behavior is preserved with include-tree. Previously, include-tree would simply textually include the header file and skip the PCM file load. This now ensures consistent behavior in edge-cases like the one in the attached test case (with `-fmodule-name=X`).

rdar://121220983
(cherry picked from commit b230339)
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Feb 12, 2024
…allback (llvm#81061)

This patch provides more information to the
`PPCallbacks::InclusionDirective()` hook. We now always pass the
suggested module, regardless of whether it was actually imported or not.
The extra `bool ModuleImported` parameter then denotes whether the
header `#include` will be automatically translated into import the the
module.

The main change is in `clang/lib/Lex/PPDirectives.cpp`, where we take
care to not modify `SuggestedModule` after it's been populated by
`LookupHeaderIncludeOrImport()`. We now exclusively use the `SM`
(`ModuleToImport`) variable instead, which has been equivalent to
`SuggestedModule` until now. This allows us to use the original
non-modified `SuggestedModule` for the callback itself.

(This patch turns out to be necessary for
swiftlang#8011).

Change-Id: I6f64614c4468ae4737b20609e065d69390d2e443
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants