[cxx-interop] Allow Swift to access non-public C++ members (#79093)

This patch introduces an a C++ class annotation, SWIFT_PRIVATE_FILEID,
which will specify where Swift extensions of that class will be allowed
to access its non-public members, e.g.:

    class SWIFT_PRIVATE_FILEID("MyModule/MyFile.swift") Foo { ... };

The goal of this feature is to help C++ developers incrementally migrate
the implementation of their C++ classes to Swift, without breaking
encapsulation and indiscriminately exposing those classes' private and
protected fields.

As an implementation detail of this feature, this patch introduces an
abstraction for file ID strings, FileIDStr, which represent a parsed pair
of module name/file name.

rdar://137764620
This commit is contained in:
John Hui
2025-02-18 11:22:44 -08:00
committed by GitHub
parent 7aa197080a
commit bdf22948ce
14 changed files with 827 additions and 4 deletions

View File

@@ -3783,6 +3783,29 @@ ArrayRef<TypeDecl *> SourceFile::getLocalTypeDecls() const {
LocalTypeDeclsRequest{mutableThis}, {});
}
std::optional<SourceFile::FileIDStr>
SourceFile::FileIDStr::parse(StringRef fileID) {
auto names = fileID.split('/');
auto moduleName = names.first;
auto fileName = names.second;
if (moduleName.empty() || fileName.empty() || !fileName.ends_with(".swift") ||
fileName.contains('/'))
return {};
return {SourceFile::FileIDStr{/*.moduleName=*/moduleName,
/*.fileName=*/fileName}};
}
bool SourceFile::FileIDStr::matches(const SourceFile *file) const {
// Never match with SourceFiles that do not correpond to a file on disk
if (file->getFilename().empty())
return false;
return moduleName == file->getParentModule()->getNameStr() &&
fileName == llvm::sys::path::filename(file->getFilename());
}
namespace {
class LocalTypeDeclCollector : public ASTWalker {
SmallVectorImpl<TypeDecl *> &results;