Skip to content

[interop][swiftToCxx] NFC, refactor out the code to print C++ impl class names and C s… #59364

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 1 commit into from
Jun 10, 2022
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
5 changes: 5 additions & 0 deletions lib/PrintAsClang/ClangSyntaxPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ void ClangSyntaxPrinter::printIdentifier(StringRef name) {
os << '_';
}

void ClangSyntaxPrinter::printBaseName(const ValueDecl *decl) {
assert(decl->getName().isSimpleName());
printIdentifier(decl->getBaseIdentifier().str());
}

void ClangSyntaxPrinter::printModuleNameCPrefix(const ModuleDecl &mod) {
os << mod.getName().str() << '_';
}
Expand Down
3 changes: 3 additions & 0 deletions lib/PrintAsClang/ClangSyntaxPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class ClangSyntaxPrinter {
/// trailing underscore.
void printIdentifier(StringRef name);

/// Print the base name of the given declaration.
void printBaseName(const ValueDecl *decl);

/// Print the C-style prefix for the given module name, that's used for
/// C type names inside the module.
void printModuleNameCPrefix(const ModuleDecl &mod);
Expand Down
68 changes: 38 additions & 30 deletions lib/PrintAsClang/PrintClangValueType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,22 @@ static void printCTypeName(raw_ostream &os, const NominalTypeDecl *type) {
ClangSyntaxPrinter printer(os);
printer.printModuleNameCPrefix(*type->getParentModule());
// FIXME: add nested type qualifiers to fully disambiguate the name.
printer.printIdentifier(type->getName().str());
printer.printBaseName(type);
}

/// Print out the C++ type name of a struct/enum declaration.
static void printCxxTypeName(raw_ostream &os, const NominalTypeDecl *type) {
// FIXME: Print namespace qualifiers for references from other modules.
// FIXME: Print class qualifiers for nested class references.
ClangSyntaxPrinter(os).printIdentifier(type->getName().str());
ClangSyntaxPrinter(os).printBaseName(type);
}

/// Print out the C++ type name of the implementation class that provides hidden
/// access to the private class APIs.
static void printCxxImplClassName(raw_ostream &os,
const NominalTypeDecl *type) {
os << "_impl_";
ClangSyntaxPrinter(os).printBaseName(type);
}

static void
Expand Down Expand Up @@ -68,28 +76,28 @@ void ClangValueTypePrinter::printStructDecl(const StructDecl *SD) {
// Print out a forward declaration of the "hidden" _impl class.
printer.printNamespace(cxx_synthesis::getCxxImplNamespaceName(),
[&](raw_ostream &os) {
os << "class _impl_";
printer.printIdentifier(SD->getName().str());
os << "class ";
printCxxImplClassName(os, SD);
os << ";\n";
});

// Print out the C++ class itself.
os << "class ";
ClangSyntaxPrinter(os).printIdentifier(SD->getName().str());
ClangSyntaxPrinter(os).printBaseName(SD);
os << " final {\n";
// FIXME: Print the other members of the struct.
os << "private:\n";

// Print out private default constructor.
os << " inline ";
printer.printIdentifier(SD->getName().str());
printer.printBaseName(SD);
os << "() {}\n";
// Print out '_make' function which returns an unitialized instance for
// passing to Swift.
os << " static inline ";
printer.printIdentifier(SD->getName().str());
printer.printBaseName(SD);
os << " _make() { return ";
printer.printIdentifier(SD->getName().str());
printer.printBaseName(SD);
os << "(); }\n";
// Print out the private accessors to the underlying Swift value storage.
os << " inline const char * _Nonnull _getOpaquePointer() const { return "
Expand All @@ -101,17 +109,16 @@ void ClangValueTypePrinter::printStructDecl(const StructDecl *SD) {
os << " alignas(" << typeSizeAlign->alignment << ") ";
os << "char _storage[" << typeSizeAlign->size << "];\n";
// Wrap up the value type.
os << " friend class " << cxx_synthesis::getCxxImplNamespaceName()
<< "::_impl_";
ClangSyntaxPrinter(os).printIdentifier(SD->getName().str());
os << " friend class " << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, SD);
os << ";\n";
os << "};\n\n";

// Print out the "hidden" _impl class.
printer.printNamespace(
cxx_synthesis::getCxxImplNamespaceName(), [&](raw_ostream &os) {
os << "class _impl_";
printer.printIdentifier(SD->getName().str());
os << "class ";
printCxxImplClassName(os, SD);
os << " {\n";
os << "public:\n";

Expand Down Expand Up @@ -140,22 +147,24 @@ void ClangValueTypePrinter::printStructDecl(const StructDecl *SD) {
printCValueTypeStorageStruct(cPrologueOS, SD, *typeSizeAlign);
}

/// Print the name of the C stub struct for passing/returning a value type
/// directly to/from swiftcc function.
static void printStubCTypeName(raw_ostream &os, const NominalTypeDecl *type) {
os << "swift_interop_stub_";
printCTypeName(os, type);
}

/// Print out the C stub struct that's used to pass/return a value type directly
/// to/from swiftcc function.
static void
printCStructStubForDirectPassing(raw_ostream &os, const NominalTypeDecl *SD,
PrimitiveTypeMapping &typeMapping,
SwiftToClangInteropContext &interopContext) {

auto printStubCTypeName = [&]() {
os << "swift_interop_stub_";
printCTypeName(os, SD);
};
// Print out a C stub for this value type.
os << "// Stub struct to be used to pass/return values to/from Swift "
"functions.\n";
os << "struct ";
printStubCTypeName();
printStubCTypeName(os, SD);
os << " {\n";
llvm::SmallVector<std::pair<clang::CharUnits, clang::CharUnits>, 8> fields;
interopContext.getIrABIDetails().enumerateDirectPassingRecordMembers(
Expand All @@ -177,7 +186,7 @@ printCStructStubForDirectPassing(raw_ostream &os, const NominalTypeDecl *SD,
os << "static inline void swift_interop_returnDirect_";
printCTypeName(os, SD);
os << "(char * _Nonnull result, struct ";
printStubCTypeName();
printStubCTypeName(os, SD);
os << " value";
os << ") __attribute__((always_inline)) {\n";
for (size_t i = 0; i < fields.size(); ++i) {
Expand All @@ -189,12 +198,12 @@ printCStructStubForDirectPassing(raw_ostream &os, const NominalTypeDecl *SD,

// Emit a stub that is used to pass value type directly to swiftcc function.
os << "static inline struct ";
printStubCTypeName();
printStubCTypeName(os, SD);
os << " swift_interop_passDirect_";
printCTypeName(os, SD);
os << "(const char * _Nonnull value) __attribute__((always_inline)) {\n";
os << " struct ";
printStubCTypeName();
printStubCTypeName(os, SD);
os << " result;\n";
for (size_t i = 0; i < fields.size(); ++i) {
os << " memcpy(&result._" << (i + 1) << ", value + "
Expand All @@ -206,8 +215,7 @@ printCStructStubForDirectPassing(raw_ostream &os, const NominalTypeDecl *SD,
}

void ClangValueTypePrinter::printCStubTypeName(const NominalTypeDecl *type) {
os << "swift_interop_stub_";
printCTypeName(os, type);
printStubCTypeName(os, type);
// Ensure the stub is declared in the header.
interopContext.runIfStubForDeclNotEmitted(type, [&]() {
printCStructStubForDirectPassing(cPrologueOS, type, typeMapping,
Expand Down Expand Up @@ -240,8 +248,8 @@ void ClangValueTypePrinter::printParameterCxxToCUseScaffold(
printCTypeName(os, type);
os << '(';
}
os << cxx_synthesis::getCxxImplNamespaceName() << "::_impl_";
ClangSyntaxPrinter(os).printIdentifier(type->getName().str());
os << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, type);
os << "::getOpaquePointer(";
cxxParamPrinter();
os << ')';
Expand All @@ -264,8 +272,8 @@ void ClangValueTypePrinter::printValueTypeIndirectReturnScaffold(
const NominalTypeDecl *type,
llvm::function_ref<void(StringRef)> bodyPrinter) {
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
os << " return " << cxx_synthesis::getCxxImplNamespaceName() << "::_impl_";
ClangSyntaxPrinter(os).printIdentifier(type->getName().str());
os << " return " << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, type);
os << "::returnNewValue([&](void * _Nonnull result) {\n ";
bodyPrinter("result");
os << ";\n";
Expand All @@ -275,8 +283,8 @@ void ClangValueTypePrinter::printValueTypeIndirectReturnScaffold(
void ClangValueTypePrinter::printValueTypeDirectReturnScaffold(
const NominalTypeDecl *type, llvm::function_ref<void()> bodyPrinter) {
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
os << " return " << cxx_synthesis::getCxxImplNamespaceName() << "::_impl_";
ClangSyntaxPrinter(os).printIdentifier(type->getName().str());
os << " return " << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, type);
os << "::returnNewValue([&](char * _Nonnull result) {\n";
os << " ";
os << cxx_synthesis::getCxxImplNamespaceName() << "::"
Expand Down