Skip to content

Commit 4b6a64e

Browse files
committed
[clang][cas] Correctly split out modules that are only imported for visibility
Modules imported for visibility only can happen when -fmodule-name matches a modular header that is imported more than once so that we trigger the correct re-exports but without trying to import a module. (cherry picked from commit d844c16) (cherry picked from commit 02b64b7)
1 parent c9b7511 commit 4b6a64e

File tree

10 files changed

+63
-20
lines changed

10 files changed

+63
-20
lines changed

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,9 @@ def warn_defined_in_function_type_macro : Extension<
918918
"macro expansion producing 'defined' has undefined behavior">,
919919
InGroup<ExpansionToDefined>;
920920

921+
def err_pp_missing_module_include_tree : Error<
922+
"no module named '%0' declared in include-tree module map">, DefaultFatal;
923+
921924
let CategoryName = "Nullability Issue" in {
922925

923926
def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">;

clang/include/clang/CAS/IncludeTree.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,17 +331,20 @@ class IncludeTree::ModuleImport : public IncludeTreeBase<ModuleImport> {
331331
public:
332332
static constexpr StringRef getNodeKind() { return "ModI"; }
333333

334-
static Expected<ModuleImport> create(ObjectStore &DB, StringRef ModuleName);
334+
static Expected<ModuleImport> create(ObjectStore &DB, StringRef ModuleName,
335+
bool VisibilityOnly);
335336

336-
StringRef getModuleName() { return getData(); }
337+
StringRef getModuleName() const { return getData().drop_front(); }
338+
/// Whether this module should only be "marked visible" rather than imported.
339+
bool visibilityOnly() const { return (bool)getData()[0]; }
337340

338341
llvm::Error print(llvm::raw_ostream &OS, unsigned Indent = 0);
339342

340343
static bool isValid(const ObjectProxy &Node) {
341344
if (!IncludeTreeBase::isValid(Node))
342345
return false;
343346
IncludeTreeBase Base(Node);
344-
return Base.getNumReferences() == 0 && !Base.getData().empty();
347+
return Base.getNumReferences() == 0 && Base.getData().size() > 1;
345348
}
346349
static bool isValid(ObjectStore &DB, ObjectRef Ref) {
347350
auto Node = DB.getProxy(Ref);

clang/include/clang/Lex/PPCachedActions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class PPCachedActions {
3939
/// The module that is imported by an \c #include directive or \c @import.
4040
struct IncludeModule {
4141
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ImportPath;
42+
// Whether this module should only be "marked visible" rather than imported.
43+
bool VisibilityOnly;
4244
};
4345

4446
virtual ~PPCachedActions() = default;

clang/lib/CAS/IncludeTree.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,12 @@ bool IncludeTree::isValid(const ObjectProxy &Node) {
212212
}
213213

214214
Expected<IncludeTree::ModuleImport>
215-
IncludeTree::ModuleImport::create(ObjectStore &DB, StringRef ModuleName) {
216-
return IncludeTreeBase::create(DB, {},
217-
llvm::arrayRefFromStringRef<char>(ModuleName));
215+
IncludeTree::ModuleImport::create(ObjectStore &DB, StringRef ModuleName,
216+
bool VisibilityOnly) {
217+
SmallString<64> Buffer;
218+
Buffer.push_back((char)VisibilityOnly);
219+
Buffer.append(ModuleName);
220+
return IncludeTreeBase::create(DB, {}, Buffer);
218221
}
219222

220223
IncludeTree::FileList::FileSizeTy
@@ -600,7 +603,11 @@ llvm::Error IncludeTree::FileList::print(llvm::raw_ostream &OS,
600603

601604
llvm::Error IncludeTree::ModuleImport::print(llvm::raw_ostream &OS,
602605
unsigned Indent) {
603-
OS << "(Module) " << getModuleName() << '\n';
606+
if (visibilityOnly())
607+
OS << "(Module for visibility only) ";
608+
else
609+
OS << "(Module) ";
610+
OS << getModuleName() << '\n';
604611
return llvm::Error::success();
605612
}
606613

clang/lib/Frontend/IncludeTreePPActions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class IncludeTreePPActions final : public PPCachedActions {
123123
Import.getModuleName().split(ModuleComponents, '.');
124124
for (StringRef Component : ModuleComponents)
125125
Path.emplace_back(PP.getIdentifierInfo(Component), IncludeLoc);
126-
return IncludeModule{std::move(Path)};
126+
return IncludeModule{std::move(Path), Import.visibilityOnly()};
127127
}
128128

129129
assert(Node->getKind() == cas::IncludeTree::NodeKind::Tree);

clang/lib/Lex/PPDirectives.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,17 +2011,36 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
20112011
return;
20122012
}
20132013
if (auto *Import = std::get_if<PPCachedActions::IncludeModule>(&Include)) {
2014-
ModuleLoadResult Imported = TheModuleLoader.loadModule(
2015-
IncludeTok.getLocation(), Import->ImportPath, Module::Hidden,
2016-
/*IsIncludeDirective=*/true);
2017-
if (!Imported) {
2018-
assert(hadModuleLoaderFatalFailure() && "unexpected failure kind");
2019-
if (hadModuleLoaderFatalFailure()) {
2020-
IncludeTok.setKind(tok::eof);
2021-
CurLexer->cutOffLexing();
2014+
ModuleLoadResult Imported;
2015+
if (Import->VisibilityOnly) {
2016+
ModuleMap &MMap = getHeaderSearchInfo().getModuleMap();
2017+
Module *M = nullptr;
2018+
for (auto &NameLoc : Import->ImportPath) {
2019+
M = MMap.lookupModuleQualified(NameLoc.first->getName(), M);
2020+
if (!M)
2021+
break;
2022+
}
2023+
if (!M) {
2024+
Diags->Report(diag::err_pp_missing_module_include_tree)
2025+
<< getLangOpts().CurrentModule;
2026+
2027+
return;
2028+
}
2029+
Imported = M;
2030+
} else {
2031+
Imported = TheModuleLoader.loadModule(
2032+
IncludeTok.getLocation(), Import->ImportPath, Module::Hidden,
2033+
/*IsIncludeDirective=*/true);
2034+
if (!Imported) {
2035+
assert(hadModuleLoaderFatalFailure() && "unexpected failure kind");
2036+
if (hadModuleLoaderFatalFailure()) {
2037+
IncludeTok.setKind(tok::eof);
2038+
CurLexer->cutOffLexing();
2039+
}
2040+
return;
20222041
}
2023-
return;
20242042
}
2043+
20252044
makeModuleVisible(Imported, EndLoc);
20262045
if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
20272046
tok::pp___include_macros)

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,10 @@ class DependencyScanningAction : public tooling::ToolAction {
458458
else
459459
Action = std::make_unique<ReadPCHAndPreprocessAction>();
460460

461+
// Normally this would be handled by GeneratePCHAction
462+
if (ScanInstance.getFrontendOpts().ProgramAction == frontend::GeneratePCH)
463+
ScanInstance.getLangOpts().CompilingPCH = true;
464+
461465
if (Error E = Controller.initialize(ScanInstance, OriginalInvocation))
462466
return reportError(std::move(E));
463467

clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,9 @@ void IncludeTreeBuilder::handleHasIncludeCheck(Preprocessor &PP, bool Result) {
397397

398398
void IncludeTreeBuilder::moduleImport(Preprocessor &PP, const Module *M,
399399
SourceLocation EndLoc) {
400-
auto Import =
401-
check(cas::IncludeTree::ModuleImport::create(DB, M->getFullModuleName()));
400+
bool VisibilityOnly = M->isForBuilding(PP.getLangOpts());
401+
auto Import = check(cas::IncludeTree::ModuleImport::create(
402+
DB, M->getFullModuleName(), VisibilityOnly));
402403
if (!Import)
403404
return;
404405

clang/test/ClangScanDeps/modules-include-tree-implementation-private.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
// CHECK: Submodule: Mod
2424
// CHECK: 3:1 [[PREFIX]]/Mod.framework/PrivateHeaders/Priv.h llvmcas://
2525
// CHECK: Submodule: Mod_Private
26+
// CHECK: 4:1 (Module for visibility only) Mod
27+
// CHECK: 5:1 (Module for visibility only) Mod_Private
2628
// CHECK: Module Map:
2729
// CHECK: Mod (framework)
2830
// CHECK: link Mod (framework)
@@ -59,6 +61,8 @@ void priv(void);
5961
//--- tu.m
6062
#import <Mod/Mod.h>
6163
#import <Mod/Priv.h>
64+
#import <Mod/Mod.h>
65+
#import <Mod/Priv.h>
6266
void tu(void) {
6367
pub();
6468
priv();

clang/test/ClangScanDeps/modules-include-tree-implementation.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
// CHECK: 2:1 [[PREFIX]]/Mod.h llvmcas://{{[[:xdigit:]]+}}
2929
// CHECK: Submodule: Mod
30-
// CHECK: 3:1 (Module) Mod
30+
// CHECK: 3:1 (Module for visibility only) Mod
3131

3232
// CHECK: Files:
3333
// CHECK: [[PREFIX]]/tu.c llvmcas://{{[[:xdigit:]]+}}

0 commit comments

Comments
 (0)