Skip to content

Commit 285e1b4

Browse files
committed
Reflection: Re-organize TypeLowering a bit to aid C API wrapper
Lowering a record type now returns the substituted types of all fields as well as their lowerings. Also fix a bit of code duplication.
1 parent 630f532 commit 285e1b4

File tree

3 files changed

+71
-48
lines changed

3 files changed

+71
-48
lines changed

include/swift/Reflection/TypeLowering.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class TypeInfo {
8282
struct FieldInfo {
8383
std::string Name;
8484
unsigned Offset;
85+
const TypeRef *TR;
8586
const TypeInfo &TI;
8687
};
8788

@@ -141,7 +142,9 @@ class TypeConverter {
141142
llvm::DenseMap<const TypeRef *, const TypeInfo *> Cache;
142143
llvm::DenseMap<std::pair<unsigned, unsigned>,
143144
const ReferenceTypeInfo *> ReferenceCache;
144-
const TypeInfo *RawPointerTI = nullptr;
145+
const TypeRef *RawPointerTR = nullptr;
146+
const TypeRef *NativeObjectTR = nullptr;
147+
const TypeRef *UnknownObjectTR = nullptr;
145148
const TypeInfo *ThickFunctionTI = nullptr;
146149

147150
public:
@@ -156,7 +159,9 @@ class TypeConverter {
156159
getReferenceTypeInfo(ReferenceKind Kind,
157160
ReferenceCounting Refcounting);
158161

159-
const TypeInfo *getRawPointerTypeInfo();
162+
const TypeRef *getRawPointerTypeRef();
163+
const TypeRef *getNativeObjectTypeRef();
164+
const TypeRef *getUnknownObjectTypeRef();
160165
const TypeInfo *getThickFunctionTypeInfo();
161166

162167
template <typename TypeInfoTy, typename... Args>

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -175,27 +175,34 @@ class RecordTypeInfoBuilder {
175175
unsigned Size, Alignment, Stride, NumExtraInhabitants;
176176
RecordKind Kind;
177177
std::vector<FieldInfo> Fields;
178+
bool Invalid;
178179

179180
public:
180181
RecordTypeInfoBuilder(TypeConverter &TC, RecordKind Kind)
181182
: TC(TC), Size(0), Alignment(1), Stride(0), NumExtraInhabitants(0),
182-
Kind(Kind) {}
183+
Kind(Kind), Invalid(false) {}
184+
185+
void addField(const std::string &Name, const TypeRef *TR) {
186+
const TypeInfo *TI = TC.getTypeInfo(TR);
187+
if (TI == nullptr) {
188+
Invalid = true;
189+
return;
190+
}
183191

184-
void addField(const std::string &Name, const TypeInfo &TI) {
185192
// FIXME: I just made this up
186193
if (Size == 0)
187-
NumExtraInhabitants = TI.getNumExtraInhabitants();
194+
NumExtraInhabitants = TI->getNumExtraInhabitants();
188195
else
189196
NumExtraInhabitants = 0;
190197

191-
unsigned fieldSize = TI.getSize();
192-
unsigned fieldAlignment = TI.getAlignment();
198+
unsigned fieldSize = TI->getSize();
199+
unsigned fieldAlignment = TI->getAlignment();
193200

194201
// Align the current size appropriately
195202
Size = ((Size + fieldAlignment - 1) & ~(fieldAlignment - 1));
196203

197204
// Add the field at the aligned offset
198-
Fields.push_back({Name, Size, TI});
205+
Fields.push_back({Name, Size, TR, *TI});
199206

200207
// Update the aggregate size
201208
Size += fieldSize;
@@ -208,6 +215,9 @@ class RecordTypeInfoBuilder {
208215
}
209216

210217
const RecordTypeInfo *build() {
218+
if (Invalid)
219+
return nullptr;
220+
211221
return TC.makeTypeInfo<RecordTypeInfo>(
212222
Size, Alignment, Stride,
213223
NumExtraInhabitants, Kind, Fields);
@@ -227,10 +237,10 @@ TypeConverter::getReferenceTypeInfo(ReferenceKind Kind,
227237
const TypeRef *TR;
228238
switch (Refcounting) {
229239
case ReferenceCounting::Native:
230-
TR = BuiltinTypeRef::create(Builder, "Bo");
240+
TR = getNativeObjectTypeRef();
231241
break;
232242
case ReferenceCounting::Unknown:
233-
TR = BuiltinTypeRef::create(Builder, "BO");
243+
TR = getUnknownObjectTypeRef();
234244
break;
235245
}
236246

@@ -254,26 +264,35 @@ TypeConverter::getThickFunctionTypeInfo() {
254264
return ThickFunctionTI;
255265

256266
RecordTypeInfoBuilder builder(*this, RecordKind::ThickFunction);
257-
auto *TI = getRawPointerTypeInfo();
258-
if (TI == nullptr)
259-
return nullptr;
260-
builder.addField("function", *TI);
261-
TI = getReferenceTypeInfo(ReferenceKind::Strong,
262-
ReferenceCounting::Native);
263-
if (TI == nullptr)
264-
return nullptr;
265-
builder.addField("context", *TI);
267+
builder.addField("function", getRawPointerTypeRef());
268+
builder.addField("context", getNativeObjectTypeRef());
266269
ThickFunctionTI = builder.build();
267270

268271
return ThickFunctionTI;
269272
}
270273

271-
const TypeInfo *TypeConverter::getRawPointerTypeInfo() {
272-
if (RawPointerTI != nullptr)
273-
return RawPointerTI;
274+
const TypeRef *TypeConverter::getRawPointerTypeRef() {
275+
if (RawPointerTR != nullptr)
276+
return RawPointerTR;
277+
278+
RawPointerTR = BuiltinTypeRef::create(Builder, "Bp");
279+
return RawPointerTR;
280+
}
281+
282+
const TypeRef *TypeConverter::getNativeObjectTypeRef() {
283+
if (NativeObjectTR != nullptr)
284+
return NativeObjectTR;
285+
286+
NativeObjectTR = BuiltinTypeRef::create(Builder, "Bo");
287+
return NativeObjectTR;
288+
}
289+
290+
const TypeRef *TypeConverter::getUnknownObjectTypeRef() {
291+
if (UnknownObjectTR != nullptr)
292+
return UnknownObjectTR;
274293

275-
RawPointerTI = getTypeInfo(BuiltinTypeRef::create(Builder, "Bp"));
276-
return RawPointerTI;
294+
UnknownObjectTR = BuiltinTypeRef::create(Builder, "BO");
295+
return UnknownObjectTR;
277296
}
278297

279298
class LowerType
@@ -286,6 +305,14 @@ class LowerType
286305
LowerType(TypeConverter &TC) : TC(TC) {}
287306

288307
const TypeInfo *visitBuiltinTypeRef(const BuiltinTypeRef *B) {
308+
if (B->getMangledName() == "Bo") {
309+
return TC.getReferenceTypeInfo(ReferenceKind::Strong,
310+
ReferenceCounting::Native);
311+
} else if (B->getMangledName() == "BO") {
312+
return TC.getReferenceTypeInfo(ReferenceKind::Strong,
313+
ReferenceCounting::Unknown);
314+
}
315+
289316
auto *descriptor = TC.getBuilder().getBuiltinTypeInfo(B);
290317
assert(descriptor != nullptr);
291318
return TC.makeTypeInfo<BuiltinTypeInfo>(descriptor);
@@ -303,12 +330,8 @@ class LowerType
303330
ReferenceCounting::Native);
304331
case FieldDescriptorKind::Struct: {
305332
RecordTypeInfoBuilder builder(TC, RecordKind::Struct);
306-
for (auto Field : TC.getBuilder().getFieldTypeRefs(TR, FD)) {
307-
auto *FieldTI = TC.getTypeInfo(Field.second);
308-
if (FieldTI == nullptr)
309-
return nullptr;
310-
builder.addField(Field.first, *FieldTI);
311-
}
333+
for (auto Field : TC.getBuilder().getFieldTypeRefs(TR, FD))
334+
builder.addField(Field.first, Field.second);
312335
return builder.build();
313336
}
314337
case FieldDescriptorKind::Enum: {
@@ -352,35 +375,22 @@ class LowerType
352375

353376
const TypeInfo *visitTupleTypeRef(const TupleTypeRef *T) {
354377
RecordTypeInfoBuilder builder(TC, RecordKind::Tuple);
355-
for (auto Element : T->getElements()) {
356-
auto *FieldTI = TC.getTypeInfo(Element);
357-
if (FieldTI == nullptr)
358-
return nullptr;
359-
builder.addField("", *FieldTI);
360-
}
378+
for (auto Element : T->getElements())
379+
builder.addField("", Element);
361380
return builder.build();
362381
}
363382

364383
const TypeInfo *visitFunctionTypeRef(const FunctionTypeRef *F) {
365384
switch (F->getFlags().getConvention()) {
366-
case FunctionMetadataConvention::Swift: {
367-
RecordTypeInfoBuilder builder(TC, RecordKind::ThickFunction);
368-
auto *TI = TC.getRawPointerTypeInfo();
369-
if (TI == nullptr)
370-
return nullptr;
371-
builder.addField("function", *TI);
372-
TI = TC.getReferenceTypeInfo(ReferenceKind::Strong,
373-
ReferenceCounting::Native);
374-
builder.addField("context", *TI);
375-
return builder.build();
376-
}
385+
case FunctionMetadataConvention::Swift:
386+
return TC.getThickFunctionTypeInfo();
377387
case FunctionMetadataConvention::Block:
378388
// FIXME: Native convention if blocks are ever supported on Linux?
379389
return TC.getReferenceTypeInfo(ReferenceKind::Strong,
380390
ReferenceCounting::Unknown);
381391
case FunctionMetadataConvention::Thin:
382392
case FunctionMetadataConvention::CFunctionPointer:
383-
return TC.getRawPointerTypeInfo();
393+
return TC.getTypeInfo(TC.getRawPointerTypeRef());
384394
}
385395
}
386396

test/Reflection/typeref_lowering.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,11 @@ V12TypeLowering14FunctionStruct
119119
// CHECK-NEXT: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
120120
// CHECK-NEXT: (field name=cFunction offset=24
121121
// CHECK-NEXT: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))
122+
123+
Bo
124+
// CHECK: (builtin Builtin.NativeObject)
125+
// CHECK-NEXT: (reference kind=strong refcounting=native)
126+
127+
BO
128+
// CHECK: (builtin Builtin.UnknownObject)
129+
// CHECK-NEXT: (reference kind=strong refcounting=unknown)

0 commit comments

Comments
 (0)