Skip to content

[IncludeTree] Suppot export_as field in ModuleMap #8493

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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions clang/include/clang/CAS/IncludeTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,16 +462,24 @@ class IncludeTree::Module : public IncludeTreeBase<Module> {
bool InferSubmodules : 1;
bool InferExplicitSubmodules : 1;
bool InferExportWildcard : 1;
bool UseExportAsModuleLinkName: 1;
ModuleFlags()
: IsFramework(false), IsExplicit(false), IsExternC(false),
IsSystem(false), InferSubmodules(false),
InferExplicitSubmodules(false), InferExportWildcard(false) {}
InferExplicitSubmodules(false), InferExportWildcard(false),
UseExportAsModuleLinkName(false) {}
};

ModuleFlags getFlags() const;

/// The name of the current (sub)module.
StringRef getName() const { return dataAfterFlags(); }
StringRef getName() const {
return dataAfterFlags().split('\0').first;
}

StringRef getExportAsModule() const {
return dataAfterFlags().split('\0').second;
}

size_t getNumSubmodules() const;

Expand Down Expand Up @@ -505,7 +513,7 @@ class IncludeTree::Module : public IncludeTreeBase<Module> {
llvm::Error print(llvm::raw_ostream &OS, unsigned Indent = 0);

static Expected<Module> create(ObjectStore &DB, StringRef ModuleName,
ModuleFlags Flags,
StringRef ExportAs, ModuleFlags Flags,
ArrayRef<ObjectRef> Submodules,
std::optional<ObjectRef> ExportList,
std::optional<ObjectRef> LinkLibraries);
Expand Down
15 changes: 13 additions & 2 deletions clang/lib/CAS/IncludeTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ static constexpr uint16_t ModuleFlagInferExplicitSubmodules = 1 << 5;
static constexpr uint16_t ModuleFlagInferInferExportWildcard = 1 << 6;
static constexpr uint16_t ModuleFlagHasExports = 1 << 7;
static constexpr uint16_t ModuleFlagHasLinkLibraries = 1 << 8;
static constexpr uint16_t ModuleFlagUseExportAsModuleLinkName = 1 << 9;

IncludeTree::Module::ModuleFlags IncludeTree::Module::getFlags() const {
uint16_t Raw = rawFlags();
Expand All @@ -344,6 +345,7 @@ IncludeTree::Module::ModuleFlags IncludeTree::Module::getFlags() const {
Flags.InferSubmodules = Raw & ModuleFlagInferSubmodules;
Flags.InferExplicitSubmodules = Raw & ModuleFlagInferExplicitSubmodules;
Flags.InferExportWildcard = Raw & ModuleFlagInferInferExportWildcard;
Flags.UseExportAsModuleLinkName = Raw & ModuleFlagUseExportAsModuleLinkName;
return Flags;
}

Expand Down Expand Up @@ -372,12 +374,14 @@ llvm::Error IncludeTree::Module::forEachSubmodule(

Expected<IncludeTree::Module>
IncludeTree::Module::create(ObjectStore &DB, StringRef ModuleName,
ModuleFlags Flags, ArrayRef<ObjectRef> Submodules,
StringRef ExportAs, ModuleFlags Flags,
ArrayRef<ObjectRef> Submodules,
std::optional<ObjectRef> ExportList,
std::optional<ObjectRef> LinkLibraries) {
// Data:
// - 2 bytes for Flags
// - ModuleName (String)
// - ModuleName (String, null-terminated)
// - (optional) ExportAsModule
// Refs:
// - Submodules (IncludeTreeModule)
// - (optional) ExportList
Expand All @@ -402,13 +406,17 @@ IncludeTree::Module::create(ObjectStore &DB, StringRef ModuleName,
RawFlags |= ModuleFlagHasExports;
if (LinkLibraries)
RawFlags |= ModuleFlagHasLinkLibraries;
if (Flags.UseExportAsModuleLinkName)
RawFlags |= ModuleFlagUseExportAsModuleLinkName;

SmallString<64> Buffer;
llvm::raw_svector_ostream BufOS(Buffer);
llvm::support::endian::Writer Writer(BufOS, llvm::support::little);
Writer.write(RawFlags);

Buffer.append(ModuleName);
Buffer.append(StringRef("\0", 1));
Buffer.append(ExportAs);

SmallVector<ObjectRef> Refs(Submodules);
if (ExportList)
Expand Down Expand Up @@ -727,6 +735,9 @@ llvm::Error IncludeTree::Module::print(llvm::raw_ostream &OS, unsigned Indent) {
if (Flags.IsSystem)
OS << " (system)";
OS << '\n';
auto ExportAs = getExportAsModule();
if (!ExportAs.empty())
OS << " export_as " << ExportAs << "\n";
if (Flags.InferSubmodules) {
if (Flags.InferExplicitSubmodules)
OS << " explicit module *";
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ static Expected<Module *> makeIncludeTreeModule(CompilerInstance &CI,
M->InferSubmodules = Flags.InferSubmodules;
M->InferExplicitSubmodules = Flags.InferExplicitSubmodules;
M->InferExportWildcard = Flags.InferExportWildcard;
M->UseExportAsModuleLinkName = Flags.UseExportAsModuleLinkName;
M->ExportAsModule = Mod.getExportAsModule();

auto ExportList = Mod.getExports();
if (!ExportList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ getIncludeTreeModule(cas::ObjectStore &DB, Module *M) {
Flags.InferSubmodules = M->InferSubmodules;
Flags.InferExplicitSubmodules = M->InferExplicitSubmodules;
Flags.InferExportWildcard = M->InferExportWildcard;
Flags.UseExportAsModuleLinkName = M->UseExportAsModuleLinkName;

bool GlobalWildcardExport = false;
SmallVector<ITModule::ExportList::Export> Exports;
Expand Down Expand Up @@ -574,8 +575,8 @@ getIncludeTreeModule(cas::ObjectStore &DB, Module *M) {
LinkLibraries = LL->getRef();
}

return ITModule::create(DB, M->Name, Flags, Submodules, ExportList,
LinkLibraries);
return ITModule::create(DB, M->Name, M->ExportAsModule, Flags, Submodules,
ExportList, LinkLibraries);
}

Expected<cas::IncludeTreeRoot>
Expand Down
67 changes: 67 additions & 0 deletions clang/test/ClangScanDeps/modules-include-tree-export-as.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// REQUIRES: ondisk_cas

// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json

// RUN: clang-scan-deps -compilation-database %t/cdb.json \
// RUN: -cas-path %t/cas -module-files-dir %t/outputs \
// RUN: -format experimental-include-tree-full -mode preprocess-dependency-directives \
// RUN: > %t/deps.json

// Extract the include-tree commands
// RUN: %deps-to-rsp %t/deps.json --module-name Top > %t/Top.rsp
// RUN: %deps-to-rsp %t/deps.json --module-name Left > %t/Left.rsp
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp

// Extract include-tree casids
// RUN: cat %t/Top.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/Top.casid
// RUN: cat %t/Left.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/Left.casid
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/Top.casid | FileCheck %s -check-prefix=TOP
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/Left.casid | FileCheck %s -check-prefix=LEFT

// TOP: Module Map:
// TOP-NEXT: Top
// TOP-NEXT: export_as Left
// LEFT: Module Map:
// LEFT-NEXT Left
// LEFT-NOT: export_as

//--- cdb.json.template
[{
"file": "DIR/tu.m",
"directory": "DIR",
"command": "clang -fsyntax-only DIR/tu.m -I DIR -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache -Rcompile-job-cache -fapinotes-modules -iapinotes-modules DIR"
}]

//--- module.modulemap
module Top {
header "Top.h"
export_as Left
export *
}
module Left {
header "Left.h"
export *
}

//--- Top.h
#pragma once
struct Top {
int x;
};
void top(void);

//--- Left.h
#include "Top.h"
void left(void);

//--- tu.m
#import "Left.h"

void tu(void) {
top(); // expected-error {{'top' is unavailable: don't use this}}
left();
}
// [email protected]:5{{'top' has been explicitly marked unavailable here}}