mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This patch introduces handling of ObjC protocols similar to how ObjC classes work. Since this only works in ObjC++, all declarations containing ObjC protocols will be protected by the __OBJC__ macro. This patch results in some `_bridgeObjC` methods being exposed, we might end up hiding those in the future, but there is no harm having them in the interop header for the interim period. rdar://136757913
205 lines
7.9 KiB
C++
205 lines
7.9 KiB
C++
//===--- PrintClangFunction.h - Printer for C/C++ functions -----*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_PRINTASCLANG_PRINTCLANGFUNCTION_H
|
|
#define SWIFT_PRINTASCLANG_PRINTCLANGFUNCTION_H
|
|
|
|
#include "OutputLanguageMode.h"
|
|
#include "swift/AST/Type.h"
|
|
#include "swift/Basic/LLVM.h"
|
|
#include "swift/ClangImporter/ClangImporter.h"
|
|
#include "swift/IRGen/GenericRequirement.h"
|
|
#include "swift/IRGen/IRABIDetailsProvider.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/MapVector.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <optional>
|
|
|
|
namespace swift {
|
|
|
|
class AbstractFunctionDecl;
|
|
class AccessorDecl;
|
|
class AnyFunctionType;
|
|
class FuncDecl;
|
|
class GenericTypeParamType;
|
|
class ModuleDecl;
|
|
class NominalTypeDecl;
|
|
class LoweredFunctionSignature;
|
|
class ParamDecl;
|
|
class ParameterList;
|
|
class PrimitiveTypeMapping;
|
|
class SwiftToClangInteropContext;
|
|
class DeclAndTypePrinter;
|
|
|
|
struct ClangRepresentation {
|
|
enum Kind { representable, objcxxonly, unsupported };
|
|
|
|
ClangRepresentation(Kind kind) : kind(kind) {}
|
|
|
|
/// Returns true if the given Swift node is unsupported in Clang in any
|
|
/// language mode.
|
|
bool isUnsupported() const { return kind == unsupported; }
|
|
|
|
/// Returns true if the given Swift node is only supported in
|
|
/// Objective C++ mode.
|
|
bool isObjCxxOnly() const { return kind == objcxxonly; }
|
|
|
|
const ClangRepresentation &merge(ClangRepresentation other) {
|
|
if (other.kind == unsupported)
|
|
kind = unsupported;
|
|
else if (kind == representable)
|
|
kind = other.kind;
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
Kind kind;
|
|
};
|
|
|
|
/// Responsible for printing a Swift function decl or type in C or C++ mode, to
|
|
/// be included in a Swift module's generated clang header.
|
|
class DeclAndTypeClangFunctionPrinter {
|
|
public:
|
|
DeclAndTypeClangFunctionPrinter(raw_ostream &os, raw_ostream &cPrologueOS,
|
|
PrimitiveTypeMapping &typeMapping,
|
|
SwiftToClangInteropContext &interopContext,
|
|
DeclAndTypePrinter &declPrinter)
|
|
: os(os), cPrologueOS(cPrologueOS), typeMapping(typeMapping),
|
|
interopContext(interopContext), declPrinter(declPrinter) {}
|
|
|
|
/// What kind of function signature should be emitted for the given Swift
|
|
/// function.
|
|
enum class FunctionSignatureKind {
|
|
/// Emit a signature for the C function prototype.
|
|
CFunctionProto,
|
|
/// Emit a signature for the inline C++ function thunk.
|
|
CxxInlineThunk
|
|
};
|
|
|
|
/// Optional modifiers that can be applied to function signature.
|
|
struct FunctionSignatureModifiers {
|
|
/// Additional qualifier to add before the function's name.
|
|
const NominalTypeDecl *qualifierContext = nullptr;
|
|
bool isStatic = false;
|
|
bool isInline = false;
|
|
bool isConst = false;
|
|
bool isNoexcept = false;
|
|
bool hasSymbolUSR = true;
|
|
/// Specific declaration that should be used to emit the symbol's
|
|
/// USR instead of the original function declaration.
|
|
const ValueDecl *symbolUSROverride = nullptr;
|
|
|
|
FunctionSignatureModifiers() {}
|
|
};
|
|
|
|
/// Print the C function declaration or the C++ function thunk that
|
|
/// corresponds to the given function declaration.
|
|
///
|
|
/// \return value describing in which Clang language mode the function is
|
|
/// supported, if any.
|
|
ClangRepresentation printFunctionSignature(
|
|
const AbstractFunctionDecl *FD, const LoweredFunctionSignature &signature,
|
|
StringRef name, Type resultTy, FunctionSignatureKind kind,
|
|
FunctionSignatureModifiers modifiers = {});
|
|
|
|
/// Print the body of the inline C++ function thunk that calls the underlying
|
|
/// Swift function.
|
|
void printCxxThunkBody(
|
|
const AbstractFunctionDecl *FD, const LoweredFunctionSignature &signature,
|
|
StringRef swiftSymbolName, const NominalTypeDecl *typeDeclContext,
|
|
const ModuleDecl *moduleContext, Type resultTy,
|
|
const ParameterList *params, bool hasThrows = false,
|
|
const AnyFunctionType *funcType = nullptr, bool isStaticMethod = false,
|
|
std::optional<IRABIDetailsProvider::MethodDispatchInfo> dispatchInfo =
|
|
std::nullopt);
|
|
|
|
/// Print the Swift method as C++ method declaration/definition, including
|
|
/// constructors.
|
|
void printCxxMethod(
|
|
DeclAndTypePrinter &declAndTypePrinter,
|
|
const NominalTypeDecl *typeDeclContext, const AbstractFunctionDecl *FD,
|
|
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
|
Type resultTy, bool isStatic, bool isDefinition,
|
|
std::optional<IRABIDetailsProvider::MethodDispatchInfo> dispatchInfo);
|
|
|
|
/// Print the C++ getter/setter method signature.
|
|
void printCxxPropertyAccessorMethod(
|
|
DeclAndTypePrinter &declAndTypePrinter,
|
|
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
|
|
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
|
Type resultTy, bool isStatic, bool isDefinition,
|
|
std::optional<IRABIDetailsProvider::MethodDispatchInfo> dispatchInfo);
|
|
|
|
/// Print the C++ subscript method.
|
|
void printCxxSubscriptAccessorMethod(
|
|
DeclAndTypePrinter &declAndTypePrinter,
|
|
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
|
|
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
|
Type resultTy, bool isDefinition,
|
|
std::optional<IRABIDetailsProvider::MethodDispatchInfo> dispatchInfo);
|
|
|
|
/// Print Swift type as C/C++ type, as the return type of a C/C++ function.
|
|
ClangRepresentation printClangFunctionReturnType(
|
|
raw_ostream &stream, Type ty, OptionalTypeKind optKind,
|
|
ModuleDecl *moduleContext, OutputLanguageMode outputLang);
|
|
|
|
static void printGenericReturnSequence(
|
|
raw_ostream &os, const GenericTypeParamType *gtpt,
|
|
llvm::function_ref<void(StringRef)> invocationPrinter,
|
|
std::optional<StringRef> initializeWithTakeFromValue = std::nullopt);
|
|
|
|
using PrinterTy =
|
|
llvm::function_ref<void(llvm::MapVector<Type, std::string> &)>;
|
|
|
|
/// Print generated C++ helper function
|
|
void printCustomCxxFunction(const SmallVector<Type> &neededTypes,
|
|
bool NeedsReturnTypes,
|
|
PrinterTy retTypeAndNamePrinter,
|
|
PrinterTy paramPrinter, bool isConstFunc,
|
|
PrinterTy bodyPrinter, ValueDecl *valueDecl,
|
|
ModuleDecl *emittedModule,
|
|
raw_ostream &outOfLineOS);
|
|
|
|
static ClangRepresentation
|
|
getTypeRepresentation(PrimitiveTypeMapping &typeMapping,
|
|
SwiftToClangInteropContext &interopContext,
|
|
DeclAndTypePrinter &declPrinter,
|
|
const ModuleDecl *emittedModule, Type ty);
|
|
|
|
/// Prints the name of the type including generic arguments.
|
|
void printTypeName(Type ty, const ModuleDecl *moduleContext);
|
|
|
|
private:
|
|
void printCxxToCFunctionParameterUse(Type type, StringRef name,
|
|
const ModuleDecl *moduleContext,
|
|
bool isInOut, bool isIndirect,
|
|
std::string directTypeEncoding,
|
|
bool isSelf);
|
|
|
|
// Print out the full type specifier that refers to the
|
|
// _impl::_impl_<typename> C++ class for the given Swift type.
|
|
void printTypeImplTypeSpecifier(Type type, const ModuleDecl *moduleContext);
|
|
|
|
bool hasKnownOptionalNullableCxxMapping(Type type);
|
|
|
|
raw_ostream &os;
|
|
raw_ostream &cPrologueOS;
|
|
PrimitiveTypeMapping &typeMapping;
|
|
SwiftToClangInteropContext &interopContext;
|
|
DeclAndTypePrinter &declPrinter;
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|