Skip to content
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
8 changes: 8 additions & 0 deletions lib/PrintAsClang/ClangSyntaxPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ void ClangSyntaxPrinter::printModuleNameCPrefix(const ModuleDecl &mod) {
os << mod.getName().str() << '_';
}

void ClangSyntaxPrinter::printModuleNamespaceQualifiersIfNeeded(
const ModuleDecl *referencedModule, const ModuleDecl *currentContext) {
if (referencedModule == currentContext)
return;
printBaseName(referencedModule);
os << "::";
}

/// Print a C++ namespace declaration with the give name and body.
void ClangSyntaxPrinter::printNamespace(
llvm::function_ref<void(raw_ostream &OS)> namePrinter,
Expand Down
6 changes: 6 additions & 0 deletions lib/PrintAsClang/ClangSyntaxPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class ClangSyntaxPrinter {
/// C type names inside the module.
void printModuleNameCPrefix(const ModuleDecl &mod);

/// Print the optional namespace qualifiers for the given module reference if
/// it's not the same as the current context.
void
printModuleNamespaceQualifiersIfNeeded(const ModuleDecl *referencedModule,
const ModuleDecl *currentContext);

/// Print a C++ namespace declaration with the give name and body.
void
printNamespace(llvm::function_ref<void(raw_ostream &OS)> namePrinter,
Expand Down
6 changes: 3 additions & 3 deletions lib/PrintAsClang/DeclAndTypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1059,9 +1059,9 @@ class DeclAndTypePrinter::Implementation
printFunctionClangAttributes(FD, funcTy);
printAvailability(FD);
os << " {\n";
funcPrinter.printCxxThunkBody(funcABI.getSymbolName(), resultTy,
FD->getParameters(), additionalParams,
funcTy->isThrowing());
funcPrinter.printCxxThunkBody(
funcABI.getSymbolName(), FD->getModuleContext(), resultTy,
FD->getParameters(), additionalParams, funcTy->isThrowing());
os << "}\n";
}

Expand Down
63 changes: 36 additions & 27 deletions lib/PrintAsClang/PrintClangFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,13 @@ class CFunctionSignatureTypePrinter
PrimitiveTypeMapping &typeMapping, OutputLanguageMode languageMode,
SwiftToClangInteropContext &interopContext,
CFunctionSignatureTypePrinterModifierDelegate modifiersDelegate,
const ModuleDecl *moduleContext,
FunctionSignatureTypeUse typeUseKind =
FunctionSignatureTypeUse::ParamType)
: ClangSyntaxPrinter(os), cPrologueOS(cPrologueOS),
typeMapping(typeMapping), interopContext(interopContext),
languageMode(languageMode), modifiersDelegate(modifiersDelegate),
typeUseKind(typeUseKind) {}
moduleContext(moduleContext), typeUseKind(typeUseKind) {}

bool printIfKnownSimpleType(const TypeDecl *typeDecl,
Optional<OptionalTypeKind> optionalKind,
Expand Down Expand Up @@ -168,11 +169,12 @@ class CFunctionSignatureTypePrinter

} else {
ClangValueTypePrinter(os, cPrologueOS, typeMapping, interopContext)
.printValueTypeParameterType(decl, languageMode, isInOutParam);
.printValueTypeParameterType(decl, languageMode, moduleContext,
isInOutParam);
}
} else
ClangValueTypePrinter(os, cPrologueOS, typeMapping, interopContext)
.printValueTypeReturnType(decl, languageMode);
.printValueTypeReturnType(decl, languageMode, moduleContext);
}

void visitPart(Type Ty, Optional<OptionalTypeKind> optionalKind,
Expand All @@ -186,6 +188,7 @@ class CFunctionSignatureTypePrinter
SwiftToClangInteropContext &interopContext;
OutputLanguageMode languageMode;
CFunctionSignatureTypePrinterModifierDelegate modifiersDelegate;
const ModuleDecl *moduleContext;
FunctionSignatureTypeUse typeUseKind;
};

Expand All @@ -195,6 +198,7 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
const AbstractFunctionDecl *FD, StringRef name, Type resultTy,
FunctionSignatureKind kind, ArrayRef<AdditionalParam> additionalParams,
FunctionSignatureModifiers modifiers) {
auto emittedModule = FD->getModuleContext();
OutputLanguageMode outputLang = kind == FunctionSignatureKind::CFunctionProto
? OutputLanguageMode::ObjC
: OutputLanguageMode::Cxx;
Expand All @@ -205,8 +209,9 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
CFunctionSignatureTypePrinterModifierDelegate delegate = {}) {
// FIXME: add support for noescape and PrintMultiPartType,
// see DeclAndTypePrinter::print.
CFunctionSignatureTypePrinter typePrinter(
os, cPrologueOS, typeMapping, outputLang, interopContext, delegate);
CFunctionSignatureTypePrinter typePrinter(os, cPrologueOS, typeMapping,
outputLang, interopContext,
delegate, emittedModule);
typePrinter.visit(ty, optionalKind, isInOutParam);

if (!name.empty()) {
Expand All @@ -228,7 +233,7 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
DeclAndTypePrinter::getObjectTypeAndOptionality(FD, resultTy);
CFunctionSignatureTypePrinter typePrinter(
os, cPrologueOS, typeMapping, outputLang, interopContext,
CFunctionSignatureTypePrinterModifierDelegate(),
CFunctionSignatureTypePrinterModifierDelegate(), emittedModule,
FunctionSignatureTypeUse::ReturnType);
// Param for indirect return cannot be marked as inout
typePrinter.visit(objTy, retKind, /*isInOutParam=*/false);
Expand Down Expand Up @@ -312,8 +317,8 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
}

void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
Type type, StringRef name, bool isInOut, bool isIndirect,
llvm::Optional<AdditionalParam::Role> paramRole) {
Type type, StringRef name, const ModuleDecl *moduleContext, bool isInOut,
bool isIndirect, llvm::Optional<AdditionalParam::Role> paramRole) {
auto namePrinter = [&]() { ClangSyntaxPrinter(os).printIdentifier(name); };
if (!isKnownCxxType(type, typeMapping) &&
!hasKnownOptionalNullableCxxMapping(type)) {
Expand All @@ -323,7 +328,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
.printParameterCxxToCUseScaffold(
isIndirect || decl->isResilient() ||
interopContext.getIrABIDetails().shouldPassIndirectly(type),
decl, namePrinter, isInOut,
decl, moduleContext, namePrinter, isInOut,
/*isSelf=*/paramRole &&
*paramRole == AdditionalParam::Role::Self);
return;
Expand All @@ -339,12 +344,14 @@ void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(

void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
const ParamDecl *param, StringRef name) {
printCxxToCFunctionParameterUse(param->getType(), name, param->isInOut());
printCxxToCFunctionParameterUse(param->getType(), name,
param->getModuleContext(), param->isInOut());
}

void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
StringRef swiftSymbolName, Type resultTy, const ParameterList *params,
ArrayRef<AdditionalParam> additionalParams, bool hasThrows) {
StringRef swiftSymbolName, const ModuleDecl *moduleContext, Type resultTy,
const ParameterList *params, ArrayRef<AdditionalParam> additionalParams,
bool hasThrows) {
if (hasThrows) {
os << " void* opaqueError = nullptr;\n";
os << " void* self = nullptr;\n";
Expand Down Expand Up @@ -382,17 +389,17 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
os << ", ";
interleaveComma(additionalParams, os, [&](const AdditionalParam &param) {
if (param.role == AdditionalParam::Role::Self && !hasThrows)
printCxxToCFunctionParameterUse(param.type, "*this", /*isInOut=*/false,
/*isIndirect=*/param.isIndirect,
param.role);
printCxxToCFunctionParameterUse(
param.type, "*this", moduleContext, /*isInOut=*/false,
/*isIndirect=*/param.isIndirect, param.role);
else if(param.role == AdditionalParam::Role::Self && hasThrows)
printCxxToCFunctionParameterUse(param.type, "self", /*isInOut=*/false,
/*isIndirect=*/param.isIndirect,
param.role);
printCxxToCFunctionParameterUse(
param.type, "self", moduleContext, /*isInOut=*/false,
/*isIndirect=*/param.isIndirect, param.role);
else if(param.role == AdditionalParam::Role::Error && hasThrows)
printCxxToCFunctionParameterUse(param.type, "&opaqueError", /*isInOut=*/false,
/*isIndirect=*/param.isIndirect,
param.role);
printCxxToCFunctionParameterUse(
param.type, "&opaqueError", moduleContext, /*isInOut=*/false,
/*isIndirect=*/param.isIndirect, param.role);
});
}

Expand All @@ -412,12 +419,13 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
interopContext);
if (isIndirect) {
valueTypePrinter.printValueTypeIndirectReturnScaffold(
decl, [&](StringRef returnParam) {
decl, moduleContext, [&](StringRef returnParam) {
printCallToCFunc(/*additionalParam=*/returnParam);
});
} else {
valueTypePrinter.printValueTypeDirectReturnScaffold(
decl, [&]() { printCallToCFunc(/*additionalParam=*/None); });
decl, moduleContext,
[&]() { printCallToCFunc(/*additionalParam=*/None); });
}
return;
}
Expand Down Expand Up @@ -464,8 +472,8 @@ void DeclAndTypeClangFunctionPrinter::printCxxMethod(
typeDeclContext->getDeclaredType(),
/*isIndirect=*/isMutating,
});
printCxxThunkBody(swiftSymbolName, resultTy, FD->getParameters(),
additionalParams, FD->hasThrows());
printCxxThunkBody(swiftSymbolName, FD->getModuleContext(), resultTy,
FD->getParameters(), additionalParams, FD->hasThrows());
os << " }\n";
}

Expand All @@ -482,7 +490,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
CFunctionSignatureTypePrinter typePrinter(
os, cPrologueOS, typeMapping, OutputLanguageMode::Cxx, interopContext,
CFunctionSignatureTypePrinterModifierDelegate(),
FunctionSignatureTypeUse::ReturnType);
accessor->getModuleContext(), FunctionSignatureTypeUse::ReturnType);
typePrinter.visit(objTy, retKind, /*isInOut=*/false);

ClangSyntaxPrinter printer(os);
Expand All @@ -506,7 +514,8 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
}
os << " {\n";
// FIXME: should it be objTy for resultTy?
printCxxThunkBody(swiftSymbolName, resultTy, accessor->getParameters(),
printCxxThunkBody(swiftSymbolName, accessor->getModuleContext(), resultTy,
accessor->getParameters(),
{AdditionalParam{AdditionalParam::Role::Self,
typeDeclContext->getDeclaredType(),
/*isIndirect=*/false}});
Expand Down
8 changes: 5 additions & 3 deletions lib/PrintAsClang/PrintClangFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include "swift/AST/Type.h"
#include "swift/Basic/LLVM.h"
#include "swift/IRGen/IRABIDetailsProvider.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
Expand All @@ -26,6 +25,7 @@ namespace swift {
class AbstractFunctionDecl;
class AccessorDecl;
class FuncDecl;
class ModuleDecl;
class NominalTypeDecl;
class ParamDecl;
class ParameterList;
Expand Down Expand Up @@ -82,7 +82,8 @@ class DeclAndTypeClangFunctionPrinter {

/// Print the body of the inline C++ function thunk that calls the underlying
/// Swift function.
void printCxxThunkBody(StringRef swiftSymbolName, Type resultTy,
void printCxxThunkBody(StringRef swiftSymbolName,
const ModuleDecl *moduleContext, Type resultTy,
const ParameterList *params,
ArrayRef<AdditionalParam> additionalParams = {},
bool hasThrows = false);
Expand All @@ -101,7 +102,8 @@ class DeclAndTypeClangFunctionPrinter {

private:
void printCxxToCFunctionParameterUse(
Type type, StringRef name, bool isInOut, bool isIndirect = false,
Type type, StringRef name, const ModuleDecl *moduleContext, bool isInOut,
bool isIndirect = false,
llvm::Optional<AdditionalParam::Role> paramRole = None);

bool hasKnownOptionalNullableCxxMapping(Type type);
Expand Down
47 changes: 31 additions & 16 deletions lib/PrintAsClang/PrintClangValueType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ static void printCTypeName(raw_ostream &os, const NominalTypeDecl *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.
static void printCxxTypeName(raw_ostream &os, const NominalTypeDecl *type,
const ModuleDecl *moduleContext) {
// FIXME: Print class qualifiers for nested class references.
ClangSyntaxPrinter(os).printBaseName(type);
ClangSyntaxPrinter printer(os);
printer.printModuleNamespaceQualifiersIfNeeded(type->getModuleContext(),
moduleContext);
printer.printBaseName(type);
}

/// Print out the C++ type name of the implementation class that provides hidden
Expand Down Expand Up @@ -236,6 +239,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
os << ";\n";
os << "};\n\n";

const auto *moduleContext = typeDecl->getModuleContext();
// Print out the "hidden" _impl class.
printer.printNamespace(
cxx_synthesis::getCxxImplNamespaceName(), [&](raw_ostream &os) {
Expand All @@ -245,19 +249,19 @@ void ClangValueTypePrinter::printValueTypeDecl(
os << "public:\n";

os << " static inline char * _Nonnull getOpaquePointer(";
printCxxTypeName(os, typeDecl);
printCxxTypeName(os, typeDecl, moduleContext);
os << " &object) { return object._getOpaquePointer(); }\n";

os << " static inline const char * _Nonnull getOpaquePointer(const ";
printCxxTypeName(os, typeDecl);
printCxxTypeName(os, typeDecl, moduleContext);
os << " &object) { return object._getOpaquePointer(); }\n";

os << " template<class T>\n";
os << " static inline ";
printCxxTypeName(os, typeDecl);
printCxxTypeName(os, typeDecl, moduleContext);
os << " returnNewValue(T callable) {\n";
os << " auto result = ";
printCxxTypeName(os, typeDecl);
printCxxTypeName(os, typeDecl, moduleContext);
os << "::_make();\n";
os << " callable(result._getOpaquePointer());\n";
os << " return result;\n";
Expand Down Expand Up @@ -348,7 +352,7 @@ void ClangValueTypePrinter::printCStubTypeName(const NominalTypeDecl *type) {

void ClangValueTypePrinter::printValueTypeParameterType(
const NominalTypeDecl *type, OutputLanguageMode outputLang,
bool isInOutParam) {
const ModuleDecl *moduleContext, bool isInOutParam) {
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
if (outputLang != OutputLanguageMode::Cxx) {
if (!isInOutParam) {
Expand All @@ -365,13 +369,14 @@ void ClangValueTypePrinter::printValueTypeParameterType(
if (!isInOutParam) {
os << "const ";
}
printCxxTypeName(os, type);
printCxxTypeName(os, type, moduleContext);
os << '&';
}

void ClangValueTypePrinter::printParameterCxxToCUseScaffold(
bool isIndirect, const NominalTypeDecl *type,
llvm::function_ref<void()> cxxParamPrinter, bool isInOut, bool isSelf) {
const ModuleDecl *moduleContext, llvm::function_ref<void()> cxxParamPrinter,
bool isInOut, bool isSelf) {
// A Swift value type is passed to its underlying Swift function
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
if (!isIndirect && !isInOut) {
Expand All @@ -383,6 +388,8 @@ void ClangValueTypePrinter::printParameterCxxToCUseScaffold(
if (isSelf) {
os << "_getOpaquePointer()";
} else {
ClangSyntaxPrinter(os).printModuleNamespaceQualifiersIfNeeded(
type->getModuleContext(), moduleContext);
os << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, type);
os << "::getOpaquePointer(";
Expand All @@ -395,21 +402,25 @@ void ClangValueTypePrinter::printParameterCxxToCUseScaffold(
}

void ClangValueTypePrinter::printValueTypeReturnType(
const NominalTypeDecl *type, OutputLanguageMode outputLang) {
const NominalTypeDecl *type, OutputLanguageMode outputLang,
const ModuleDecl *moduleContext) {
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
if (outputLang == OutputLanguageMode::Cxx) {
printCxxTypeName(os, type);
printCxxTypeName(os, type, moduleContext);
} else {
os << "struct ";
printCStubTypeName(type);
}
}

void ClangValueTypePrinter::printValueTypeIndirectReturnScaffold(
const NominalTypeDecl *type,
const NominalTypeDecl *type, const ModuleDecl *moduleContext,
llvm::function_ref<void(StringRef)> bodyPrinter) {
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
os << " return " << cxx_synthesis::getCxxImplNamespaceName() << "::";
os << " return ";
ClangSyntaxPrinter(os).printModuleNamespaceQualifiersIfNeeded(
type->getModuleContext(), moduleContext);
os << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, type);
os << "::returnNewValue([&](void * _Nonnull result) {\n ";
bodyPrinter("result");
Expand All @@ -418,9 +429,13 @@ void ClangValueTypePrinter::printValueTypeIndirectReturnScaffold(
}

void ClangValueTypePrinter::printValueTypeDirectReturnScaffold(
const NominalTypeDecl *type, llvm::function_ref<void()> bodyPrinter) {
const NominalTypeDecl *type, const ModuleDecl *moduleContext,
llvm::function_ref<void()> bodyPrinter) {
assert(isa<StructDecl>(type) || isa<EnumDecl>(type));
os << " return " << cxx_synthesis::getCxxImplNamespaceName() << "::";
os << " return ";
ClangSyntaxPrinter(os).printModuleNamespaceQualifiersIfNeeded(
type->getModuleContext(), moduleContext);
os << cxx_synthesis::getCxxImplNamespaceName() << "::";
printCxxImplClassName(os, type);
os << "::returnNewValue([&](char * _Nonnull result) {\n";
os << " ";
Expand Down
Loading