Skip to content

Commit cec4b82

Browse files
eecksteinMaxDesiatov
authored andcommitted
swift SIL: add some SIL type related bridging
* `Function.argumentTypes` and `Function.resultType` * `Type.isNominal`, `Type.isClass`, `Type.isTuple`, `Type.isStruct` and `Type.isEnum` * `Type.getFieldIndexOfNominal` * `Type.getFieldTypeOfNominal` * `Type.tupleElements` * `Type.description` for better debugging # Conflicts: # SwiftCompilerSources/Sources/SIL/Type.swift # SwiftCompilerSources/Sources/SIL/Utils.swift # SwiftCompilerSources/Sources/SIL/Value.swift # include/swift/SIL/SILBridging.h # lib/SIL/Utils/SILBridging.cpp
1 parent b964dba commit cec4b82

File tree

6 files changed

+191
-12
lines changed

6 files changed

+191
-12
lines changed

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,27 @@ final public class Function : CustomStringConvertible, HasName {
4747
assert(selfIdx >= 0)
4848
return selfIdx
4949
}
50+
51+
public var argumentTypes: ArgumentTypeArray { ArgumentTypeArray(function: self) }
52+
public var resultType: Type { SILFunction_getSILResultType(bridged).type }
5053

5154
public var bridged: BridgedFunction { BridgedFunction(obj: SwiftObject(self)) }
5255
}
5356

5457
public func == (lhs: Function, rhs: Function) -> Bool { lhs === rhs }
5558
public func != (lhs: Function, rhs: Function) -> Bool { lhs !== rhs }
5659

60+
public struct ArgumentTypeArray : RandomAccessCollection, FormattedLikeArray {
61+
fileprivate let function: Function
62+
63+
public var startIndex: Int { return 0 }
64+
public var endIndex: Int { SILFunction_getNumSILArguments(function.bridged) }
65+
66+
public subscript(_ index: Int) -> Type {
67+
SILFunction_getSILArgumentType(function.bridged, index).type
68+
}
69+
}
70+
5771
// Bridging utilities
5872

5973
extension BridgedFunction {

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,55 @@
1212

1313
import SILBridging
1414

15-
public struct Type {
16-
public let bridged: BridgedType
17-
15+
public struct Type : CustomStringConvertible, CustomReflectable {
16+
var bridged: BridgedType
17+
1818
public var isAddress: Bool { SILType_isAddress(bridged) != 0 }
1919
public var isObject: Bool { !isAddress }
2020

2121
public func isTrivial(in function: Function) -> Bool {
2222
return SILType_isTrivial(bridged, function.bridged) != 0
2323
}
24+
25+
public var isNominal: Bool { SILType_isNominal(bridged) != 0 }
26+
public var isClass: Bool { SILType_isClass(bridged) != 0 }
27+
public var isStruct: Bool { SILType_isStruct(bridged) != 0 }
28+
public var isTuple: Bool { SILType_isTuple(bridged) != 0 }
29+
public var isEnum: Bool { SILType_isEnum(bridged) != 0 }
30+
31+
public var tupleElements: TupleElementArray { TupleElementArray(type: self) }
32+
33+
public func isNonTrivialOrContainsRawPointer(in function: Function) -> Bool {
34+
return SILType_isNonTrivialOrContainsRawPointer(bridged, function.bridged) != 0
35+
}
36+
37+
public func getFieldIndexOfNominal(fieldName: String) -> Int? {
38+
let idx = fieldName.withBridgedStringRef {
39+
SILType_getFieldIdxOfNominalType(bridged, $0)
40+
}
41+
return idx >= 0 ? idx : nil
42+
}
43+
44+
public func getFieldTypeOfNominal(fieldIndex: Int, in function: Function) -> Type {
45+
SILType_getTypeOfField(bridged, fieldIndex, function.bridged).type
46+
}
47+
48+
public var description: String { SILType_debugDescription(bridged).takeString() }
49+
50+
public var customMirror: Mirror { Mirror(self, children: []) }
2451
}
2552

26-
extension Type: Equatable {
27-
public static func == (lhs: Type, rhs: Type) -> Bool {
28-
lhs.bridged.typePtr == rhs.bridged.typePtr
53+
public struct TupleElementArray : RandomAccessCollection, FormattedLikeArray {
54+
fileprivate let type: Type
55+
56+
public var startIndex: Int { return 0 }
57+
public var endIndex: Int { SILType_getNumTupleElements(type.bridged) }
58+
59+
public subscript(_ index: Int) -> Type {
60+
SILType_getTupleElementType(type.bridged, index).type
2961
}
3062
}
63+
64+
extension BridgedType {
65+
var type: Type { Type(bridged: self) }
66+
}

SwiftCompilerSources/Sources/SIL/Utils.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,12 @@ extension Optional where Wrapped == UnsafeMutablePointer<BridgedSwiftObject> {
219219
return nil
220220
}
221221
}
222+
223+
extension BridgedArrayRef {
224+
func withElements<T, R>(ofType ty: T.Type, _ c: (UnsafeBufferPointer<T>) -> R) -> R {
225+
return data.withMemoryRebound(to: ty, capacity: numElements) { (ptr: UnsafePointer<T>) -> R in
226+
let buffer = UnsafeBufferPointer(start: ptr, count: numElements)
227+
return c(buffer)
228+
}
229+
}
230+
}

SwiftCompilerSources/Sources/SIL/Value.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ extension Value {
2727
UseList(SILValue_firstUse(bridged))
2828
}
2929

30-
public var type: Type {
31-
Type(bridged: SILValue_getType(bridged))
32-
}
30+
public var type: Type { SILValue_getType(bridged).type }
3331

3432
public var hashable: HashableValue { ObjectIdentifier(self) }
3533

@@ -61,4 +59,4 @@ final class PlaceholderValue : Value {
6159

6260
extension OptionalBridgedValue {
6361
var value: Value? { obj.getAs(AnyObject.self) as? Value }
64-
}
62+
}

include/swift/SIL/SILBridging.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ extern "C" {
2222

2323
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
2424

25+
typedef intptr_t SwiftInt;
26+
2527
typedef struct {
2628
const unsigned char * _Nullable data;
2729
size_t length;
@@ -156,8 +158,6 @@ typedef enum {
156158
#include "swift/AST/Builtins.def"
157159
} BridgedBuiltinID;
158160

159-
typedef intptr_t SwiftInt;
160-
161161
void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype);
162162

163163
void OStream_write(BridgedOStream os, BridgedStringRef str);
@@ -175,6 +175,9 @@ OptionalBridgedBasicBlock SILFunction_firstBlock(BridgedFunction function);
175175
OptionalBridgedBasicBlock SILFunction_lastBlock(BridgedFunction function);
176176
SwiftInt SILFunction_numIndirectResultArguments(BridgedFunction function);
177177
SwiftInt SILFunction_getSelfArgumentIndex(BridgedFunction function);
178+
SwiftInt SILFunction_getNumSILArguments(BridgedFunction function);
179+
BridgedType SILFunction_getSILArgumentType(BridgedFunction function, SwiftInt idx);
180+
BridgedType SILFunction_getSILResultType(BridgedFunction function);
178181

179182
BridgedStringRef SILGlobalVariable_getName(BridgedGlobalVar global);
180183
BridgedStringRef SILGlobalVariable_debugDescription(BridgedGlobalVar global);
@@ -201,8 +204,21 @@ BridgedStringRef SILNode_debugDescription(BridgedNode node);
201204
OptionalBridgedOperand SILValue_firstUse(BridgedValue value);
202205
BridgedType SILValue_getType(BridgedValue value);
203206

207+
BridgedStringRef SILType_debugDescription(BridgedType);
204208
SwiftInt SILType_isAddress(BridgedType);
205209
SwiftInt SILType_isTrivial(BridgedType, BridgedFunction);
210+
SwiftInt SILType_isNonTrivialOrContainsRawPointer(BridgedType, BridgedFunction);
211+
SwiftInt SILType_isNominal(BridgedType type);
212+
SwiftInt SILType_isClass(BridgedType type);
213+
SwiftInt SILType_isStruct(BridgedType type);
214+
SwiftInt SILType_isTuple(BridgedType type);
215+
SwiftInt SILType_isEnum(BridgedType type);
216+
SwiftInt SILType_getFieldIdxOfNominalType(BridgedType type,
217+
BridgedStringRef fieldName);
218+
BridgedType SILType_getTypeOfField(BridgedType type, SwiftInt fieldIndex,
219+
BridgedFunction inFunction);
220+
SwiftInt SILType_getNumTupleElements(BridgedType type);
221+
BridgedType SILType_getTupleElementType(BridgedType type, SwiftInt elementIdx);
206222
BridgedSubstitutionMap SILType_getContextSubstitutionMap(BridgedType);
207223

208224
BridgedBasicBlock SILArgument_getParent(BridgedArgument argument);

lib/SIL/Utils/SILBridging.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,26 @@ SwiftInt SILFunction_getSelfArgumentIndex(BridgedFunction function) {
195195
return fTy->getNumParameters() + fTy->getNumIndirectFormalResults() - 1;
196196
}
197197

198+
SwiftInt SILFunction_getNumSILArguments(BridgedFunction function) {
199+
SILFunction *f = castToFunction(function);
200+
SILFunctionConventions conv(f->getConventionsInContext());
201+
return conv.getNumSILArguments();
202+
}
203+
204+
BridgedType SILFunction_getSILArgumentType(BridgedFunction function, SwiftInt idx) {
205+
SILFunction *f = castToFunction(function);
206+
SILFunctionConventions conv(f->getConventionsInContext());
207+
SILType argTy = conv.getSILArgumentType(idx, f->getTypeExpansionContext());
208+
return {argTy.getOpaqueValue()};
209+
}
210+
211+
BridgedType SILFunction_getSILResultType(BridgedFunction function) {
212+
SILFunction *f = castToFunction(function);
213+
SILFunctionConventions conv(f->getConventionsInContext());
214+
SILType resTy = conv.getSILResultType(f->getTypeExpansionContext());
215+
return {resTy.getOpaqueValue()};
216+
}
217+
198218
//===----------------------------------------------------------------------===//
199219
// SILBasicBlock
200220
//===----------------------------------------------------------------------===//
@@ -325,6 +345,13 @@ BridgedType SILValue_getType(BridgedValue value) {
325345
// SILType
326346
//===----------------------------------------------------------------------===//
327347

348+
BridgedStringRef SILType_debugDescription(BridgedType type) {
349+
std::string str;
350+
llvm::raw_string_ostream os(str);
351+
castToSILType(type).print(os);
352+
return getCopiedBridgedStringRef(str, /*removeTrailingNewline*/ true);
353+
}
354+
328355
SwiftInt SILType_isAddress(BridgedType type) {
329356
return castToSILType(type).isAddress();
330357
}
@@ -333,6 +360,85 @@ SwiftInt SILType_isTrivial(BridgedType type, BridgedFunction function) {
333360
return castToSILType(type).isTrivial(*castToFunction(function));
334361
}
335362

363+
SwiftInt SILType_isNominal(BridgedType type) {
364+
return castToSILType(type).getNominalOrBoundGenericNominal() ? 1 : 0;
365+
}
366+
367+
SwiftInt SILType_isClass(BridgedType type) {
368+
return castToSILType(type).getClassOrBoundGenericClass() ? 1 : 0;
369+
}
370+
371+
SwiftInt SILType_isStruct(BridgedType type) {
372+
return castToSILType(type).getStructOrBoundGenericStruct() ? 1 : 0;
373+
}
374+
375+
SwiftInt SILType_isTuple(BridgedType type) {
376+
return castToSILType(type).is<TupleType>() ? 1 : 0;
377+
}
378+
379+
SwiftInt SILType_isEnum(BridgedType type) {
380+
return castToSILType(type).getEnumOrBoundGenericEnum() ? 1 : 0;
381+
}
382+
383+
SwiftInt SILType_isNonTrivialOrContainsRawPointer(BridgedType type,
384+
BridgedFunction function) {
385+
SILFunction *f = castToFunction(function);
386+
return castToSILType(type).isNonTrivialOrContainsRawPointer(*f);
387+
}
388+
389+
SwiftInt SILType_getFieldIdxOfNominalType(BridgedType type,
390+
BridgedStringRef fieldName) {
391+
SILType ty = castToSILType(type);
392+
auto *nominal = ty.getNominalOrBoundGenericNominal();
393+
if (!nominal)
394+
return -1;
395+
396+
SmallVector<NominalTypeDecl *, 5> decls;
397+
decls.push_back(nominal);
398+
if (auto *cd = dyn_cast<ClassDecl>(nominal)) {
399+
while ((cd = cd->getSuperclassDecl()) != nullptr) {
400+
decls.push_back(cd);
401+
}
402+
}
403+
std::reverse(decls.begin(), decls.end());
404+
405+
SwiftInt idx = 0;
406+
StringRef fieldNm((const char *)fieldName.data, fieldName.length);
407+
for (auto *decl : decls) {
408+
for (VarDecl *field : decl->getStoredProperties()) {
409+
if (field->getName().str() == fieldNm)
410+
return idx;
411+
idx++;
412+
}
413+
}
414+
return -1;
415+
}
416+
417+
BridgedType SILType_getTypeOfField(BridgedType type, SwiftInt fieldIndex,
418+
BridgedFunction inFunction) {
419+
SILType ty = castToSILType(type);
420+
auto *nominal = ty.getNominalOrBoundGenericNominal();
421+
assert(nominal);
422+
423+
VarDecl *field = getIndexedField(nominal, (unsigned)fieldIndex);
424+
assert(field);
425+
426+
SILFunction *f = castToFunction(inFunction);
427+
SILType fieldTy = ty.getFieldType(field, f->getModule(),f->getTypeExpansionContext());
428+
return {fieldTy.getOpaqueValue()};
429+
}
430+
431+
SwiftInt SILType_getNumTupleElements(BridgedType type) {
432+
TupleType *tupleTy = castToSILType(type).castTo<TupleType>();
433+
return tupleTy->getNumElements();
434+
}
435+
436+
BridgedType SILType_getTupleElementType(BridgedType type, SwiftInt elementIdx) {
437+
SILType ty = castToSILType(type);
438+
SILType elmtTy = ty.getTupleElementType((unsigned)elementIdx);
439+
return {elmtTy.getOpaqueValue()};
440+
}
441+
336442
//===----------------------------------------------------------------------===//
337443
// SILGlobalVariable
338444
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)