[interop][SwiftToCxx] print out value witness table definition in swift::_impl

This commit is contained in:
Alex Lorenz
2022-06-13 14:11:41 -07:00
parent 9254c47b2c
commit a65ddbe997
4 changed files with 89 additions and 0 deletions

View File

@@ -51,6 +51,16 @@ static void emitObjCConditional(raw_ostream &out,
out << "#endif\n";
}
static void writePtrauthPrologue(raw_ostream &os) {
os << "#if __has_include(<ptrauth.h>)\n";
os << "# include <ptrauth.h>\n";
os << "#else\n";
os << "# ifndef __ptrauth_swift_value_witness_function_pointer\n";
os << "# define __ptrauth_swift_value_witness_function_pointer(x)\n";
os << "# endif\n";
os << "#endif\n";
}
static void writePrologue(raw_ostream &out, ASTContext &ctx,
StringRef macroGuard) {
@@ -98,6 +108,7 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
"#include <stdbool.h>\n"
"#include <string.h>\n";
});
writePtrauthPrologue(out);
out << "\n"
"#if !defined(SWIFT_TYPEDEFS)\n"
"# define SWIFT_TYPEDEFS 1\n"

View File

@@ -14,9 +14,11 @@
#include "ClangSyntaxPrinter.h"
#include "PrimitiveTypeMapping.h"
#include "SwiftToClangInteropContext.h"
#include "swift/ABI/MetadataValues.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Type.h"
#include "swift/IRGen/IRABIDetailsProvider.h"
#include "llvm/ADT/STLExtras.h"
using namespace swift;
@@ -60,6 +62,49 @@ static void printKnownType(
printKnownStruct(typeMapping, os, name, typeRecord);
}
static void printValueWitnessTableFunctionType(raw_ostream &os, StringRef name,
StringRef returnType,
std::string paramTypes,
uint16_t ptrauthDisc) {
os << "using ValueWitness" << name << "Ty = " << returnType << "(*)("
<< paramTypes << ") __ptrauth_swift_value_witness_function_pointer("
<< ptrauthDisc << ");\n";
}
static std::string makeParams(const char *arg) { return arg; }
template <class... T>
static std::string makeParams(const char *arg, const T... args) {
return std::string(arg) + ", " + makeParams(args...);
}
static void printValueWitnessTable(raw_ostream &os) {
std::string members;
llvm::raw_string_ostream membersOS(members);
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
#define DATA_VALUE_WITNESS(lowerId, upperId, type) \
membersOS << " " << type << " " << #lowerId << ";\n";
#define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \
printValueWitnessTableFunctionType( \
os, #upperId, returnType, makeParams paramTypes, \
SpecialPointerAuthDiscriminators::upperId); \
membersOS << " ValueWitness" << #upperId << "Ty _Nonnull " << #lowerId \
<< ";\n";
#define MUTABLE_VALUE_TYPE "void * _Nonnull"
#define IMMUTABLE_VALUE_TYPE "const void * _Nonnull"
#define MUTABLE_BUFFER_TYPE "void * _Nonnull"
#define IMMUTABLE_BUFFER_TYPE "const void * _Nonnull"
#define TYPE_TYPE "void * _Nonnull"
#define SIZE_TYPE "size_t"
#define INT_TYPE "int"
#define UINT_TYPE "unsigned"
#define VOID_TYPE "void"
#include "swift/ABI/ValueWitness.def"
os << "\nstruct ValueWitnessTable {\n" << membersOS.str() << "};\n";
}
static void printTypeMetadataResponseType(SwiftToClangInteropContext &ctx,
PrimitiveTypeMapping &typeMapping,
raw_ostream &os) {
@@ -82,6 +127,8 @@ void swift::printSwiftToClangCoreScaffold(SwiftToClangInteropContext &ctx,
cxx_synthesis::getCxxImplNamespaceName(), [&](raw_ostream &) {
printer.printExternC([&](raw_ostream &os) {
printTypeMetadataResponseType(ctx, typeMapping, os);
os << "\n";
printValueWitnessTable(os);
});
});
});

View File

@@ -23,6 +23,30 @@
// CHECK-NEXT: // Swift type metadata request type.
// CHECK-NEXT: typedef uint{{.*}}_t MetadataRequestTy;
// CHECK-EMPTY:
// CHECK-NEXT: using ValueWitnessInitializeBufferWithCopyOfBufferTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessDestroyTy = void(*)(void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessInitializeWithCopyTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessAssignWithCopyTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessInitializeWithTakeTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessAssignWithTakeTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessGetEnumTagSinglePayloadTy = unsigned(*)(const void * _Nonnull, unsigned, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-NEXT: using ValueWitnessStoreEnumTagSinglePayloadTy = void(*)(void * _Nonnull, unsigned, unsigned, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
// CHECK-EMPTY:
// CHECK-NEXT: struct ValueWitnessTable {
// CHECK-NEXT: ValueWitnessInitializeBufferWithCopyOfBufferTy _Nonnull initializeBufferWithCopyOfBuffer;
// CHECK-NEXT: ValueWitnessDestroyTy _Nonnull destroy;
// CHECK-NEXT: ValueWitnessInitializeWithCopyTy _Nonnull initializeWithCopy;
// CHECK-NEXT: ValueWitnessAssignWithCopyTy _Nonnull assignWithCopy;
// CHECK-NEXT: ValueWitnessInitializeWithTakeTy _Nonnull initializeWithTake;
// CHECK-NEXT: ValueWitnessAssignWithTakeTy _Nonnull assignWithTake;
// CHECK-NEXT: ValueWitnessGetEnumTagSinglePayloadTy _Nonnull getEnumTagSinglePayload;
// CHECK-NEXT: ValueWitnessStoreEnumTagSinglePayloadTy _Nonnull storeEnumTagSinglePayload;
// CHECK-NEXT: size_t size;
// CHECK-NEXT: size_t stride;
// CHECK-NEXT: unsigned flags;
// CHECK-NEXT: unsigned extraInhabitantCount;
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: #ifdef __cplusplus
// CHECK-NEXT: }
// CHECK-NEXT: #endif

View File

@@ -35,6 +35,13 @@
// CHECK-NEXT: #include <stdbool.h>
// CHECK-NEXT: #include <string.h>
// CHECK-NEXT: #endif
// CHECK-NEXT: #if __has_include(<ptrauth.h>)
// CHECK-NEXT: # include <ptrauth.h>
// CHECK-NEXT: #else
// CHECK-NEXT: # ifndef __ptrauth_swift_value_witness_function_pointer
// CHECK-NEXT: # define __ptrauth_swift_value_witness_function_pointer(x)
// CHECK-NEXT: # endif
// CHECK-NEXT: #endif
// CHECK-LABEL: !defined(SWIFT_TYPEDEFS)
// CHECK-NEXT: # define SWIFT_TYPEDEFS 1