Skip to content

Commit a65ddbe

Browse files
committed
[interop][SwiftToCxx] print out value witness table definition in swift::_impl
1 parent 9254c47 commit a65ddbe

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

lib/PrintAsClang/PrintAsClang.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ static void emitObjCConditional(raw_ostream &out,
5151
out << "#endif\n";
5252
}
5353

54+
static void writePtrauthPrologue(raw_ostream &os) {
55+
os << "#if __has_include(<ptrauth.h>)\n";
56+
os << "# include <ptrauth.h>\n";
57+
os << "#else\n";
58+
os << "# ifndef __ptrauth_swift_value_witness_function_pointer\n";
59+
os << "# define __ptrauth_swift_value_witness_function_pointer(x)\n";
60+
os << "# endif\n";
61+
os << "#endif\n";
62+
}
63+
5464
static void writePrologue(raw_ostream &out, ASTContext &ctx,
5565
StringRef macroGuard) {
5666

@@ -98,6 +108,7 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
98108
"#include <stdbool.h>\n"
99109
"#include <string.h>\n";
100110
});
111+
writePtrauthPrologue(out);
101112
out << "\n"
102113
"#if !defined(SWIFT_TYPEDEFS)\n"
103114
"# define SWIFT_TYPEDEFS 1\n"

lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
#include "ClangSyntaxPrinter.h"
1515
#include "PrimitiveTypeMapping.h"
1616
#include "SwiftToClangInteropContext.h"
17+
#include "swift/ABI/MetadataValues.h"
1718
#include "swift/AST/Decl.h"
1819
#include "swift/AST/Type.h"
1920
#include "swift/IRGen/IRABIDetailsProvider.h"
21+
#include "llvm/ADT/STLExtras.h"
2022

2123
using namespace swift;
2224

@@ -60,6 +62,49 @@ static void printKnownType(
6062
printKnownStruct(typeMapping, os, name, typeRecord);
6163
}
6264

65+
static void printValueWitnessTableFunctionType(raw_ostream &os, StringRef name,
66+
StringRef returnType,
67+
std::string paramTypes,
68+
uint16_t ptrauthDisc) {
69+
os << "using ValueWitness" << name << "Ty = " << returnType << "(*)("
70+
<< paramTypes << ") __ptrauth_swift_value_witness_function_pointer("
71+
<< ptrauthDisc << ");\n";
72+
}
73+
74+
static std::string makeParams(const char *arg) { return arg; }
75+
76+
template <class... T>
77+
static std::string makeParams(const char *arg, const T... args) {
78+
return std::string(arg) + ", " + makeParams(args...);
79+
}
80+
81+
static void printValueWitnessTable(raw_ostream &os) {
82+
std::string members;
83+
llvm::raw_string_ostream membersOS(members);
84+
85+
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
86+
#define DATA_VALUE_WITNESS(lowerId, upperId, type) \
87+
membersOS << " " << type << " " << #lowerId << ";\n";
88+
#define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \
89+
printValueWitnessTableFunctionType( \
90+
os, #upperId, returnType, makeParams paramTypes, \
91+
SpecialPointerAuthDiscriminators::upperId); \
92+
membersOS << " ValueWitness" << #upperId << "Ty _Nonnull " << #lowerId \
93+
<< ";\n";
94+
#define MUTABLE_VALUE_TYPE "void * _Nonnull"
95+
#define IMMUTABLE_VALUE_TYPE "const void * _Nonnull"
96+
#define MUTABLE_BUFFER_TYPE "void * _Nonnull"
97+
#define IMMUTABLE_BUFFER_TYPE "const void * _Nonnull"
98+
#define TYPE_TYPE "void * _Nonnull"
99+
#define SIZE_TYPE "size_t"
100+
#define INT_TYPE "int"
101+
#define UINT_TYPE "unsigned"
102+
#define VOID_TYPE "void"
103+
#include "swift/ABI/ValueWitness.def"
104+
105+
os << "\nstruct ValueWitnessTable {\n" << membersOS.str() << "};\n";
106+
}
107+
63108
static void printTypeMetadataResponseType(SwiftToClangInteropContext &ctx,
64109
PrimitiveTypeMapping &typeMapping,
65110
raw_ostream &os) {
@@ -82,6 +127,8 @@ void swift::printSwiftToClangCoreScaffold(SwiftToClangInteropContext &ctx,
82127
cxx_synthesis::getCxxImplNamespaceName(), [&](raw_ostream &) {
83128
printer.printExternC([&](raw_ostream &os) {
84129
printTypeMetadataResponseType(ctx, typeMapping, os);
130+
os << "\n";
131+
printValueWitnessTable(os);
85132
});
86133
});
87134
});

test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,30 @@
2323
// CHECK-NEXT: // Swift type metadata request type.
2424
// CHECK-NEXT: typedef uint{{.*}}_t MetadataRequestTy;
2525
// CHECK-EMPTY:
26+
// CHECK-NEXT: using ValueWitnessInitializeBufferWithCopyOfBufferTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
27+
// CHECK-NEXT: using ValueWitnessDestroyTy = void(*)(void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
28+
// CHECK-NEXT: using ValueWitnessInitializeWithCopyTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
29+
// CHECK-NEXT: using ValueWitnessAssignWithCopyTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
30+
// CHECK-NEXT: using ValueWitnessInitializeWithTakeTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
31+
// CHECK-NEXT: using ValueWitnessAssignWithTakeTy = void * _Nonnull(*)(void * _Nonnull, void * _Nonnull, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
32+
// CHECK-NEXT: using ValueWitnessGetEnumTagSinglePayloadTy = unsigned(*)(const void * _Nonnull, unsigned, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
33+
// CHECK-NEXT: using ValueWitnessStoreEnumTagSinglePayloadTy = void(*)(void * _Nonnull, unsigned, unsigned, void * _Nonnull) __ptrauth_swift_value_witness_function_pointer(
34+
// CHECK-EMPTY:
35+
// CHECK-NEXT: struct ValueWitnessTable {
36+
// CHECK-NEXT: ValueWitnessInitializeBufferWithCopyOfBufferTy _Nonnull initializeBufferWithCopyOfBuffer;
37+
// CHECK-NEXT: ValueWitnessDestroyTy _Nonnull destroy;
38+
// CHECK-NEXT: ValueWitnessInitializeWithCopyTy _Nonnull initializeWithCopy;
39+
// CHECK-NEXT: ValueWitnessAssignWithCopyTy _Nonnull assignWithCopy;
40+
// CHECK-NEXT: ValueWitnessInitializeWithTakeTy _Nonnull initializeWithTake;
41+
// CHECK-NEXT: ValueWitnessAssignWithTakeTy _Nonnull assignWithTake;
42+
// CHECK-NEXT: ValueWitnessGetEnumTagSinglePayloadTy _Nonnull getEnumTagSinglePayload;
43+
// CHECK-NEXT: ValueWitnessStoreEnumTagSinglePayloadTy _Nonnull storeEnumTagSinglePayload;
44+
// CHECK-NEXT: size_t size;
45+
// CHECK-NEXT: size_t stride;
46+
// CHECK-NEXT: unsigned flags;
47+
// CHECK-NEXT: unsigned extraInhabitantCount;
48+
// CHECK-NEXT: };
49+
// CHECK-EMPTY:
2650
// CHECK-NEXT: #ifdef __cplusplus
2751
// CHECK-NEXT: }
2852
// CHECK-NEXT: #endif

test/PrintAsCxx/empty.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535
// CHECK-NEXT: #include <stdbool.h>
3636
// CHECK-NEXT: #include <string.h>
3737
// CHECK-NEXT: #endif
38+
// CHECK-NEXT: #if __has_include(<ptrauth.h>)
39+
// CHECK-NEXT: # include <ptrauth.h>
40+
// CHECK-NEXT: #else
41+
// CHECK-NEXT: # ifndef __ptrauth_swift_value_witness_function_pointer
42+
// CHECK-NEXT: # define __ptrauth_swift_value_witness_function_pointer(x)
43+
// CHECK-NEXT: # endif
44+
// CHECK-NEXT: #endif
3845

3946
// CHECK-LABEL: !defined(SWIFT_TYPEDEFS)
4047
// CHECK-NEXT: # define SWIFT_TYPEDEFS 1

0 commit comments

Comments
 (0)