12
12
//
13
13
//===----------------------------------------------------------------------===//
14
14
15
- extension SwiftStandardLibraryTypes {
15
+ extension CType {
16
16
/// Lower the given Swift type down to a its corresponding C type.
17
17
///
18
18
/// This operation only supports the subset of Swift types that are
19
19
/// representable in a Swift `@_cdecl` function. If lowering an arbitrary
20
20
/// Swift function, first go through Swift -> cdecl lowering.
21
- func cdeclToCLowering ( _ swiftType : SwiftType ) throws -> CType {
22
- switch swiftType {
21
+ init ( cdeclType : SwiftType ) throws {
22
+ switch cdeclType {
23
23
case . nominal( let nominalType) :
24
- if let knownType = self [ nominalType. nominalTypeDecl] {
25
- return try knownType. loweredCType ( )
24
+ if let knownType = nominalType. nominalTypeDecl. knownStandardLibraryType,
25
+ let primitiveCType = knownType. primitiveCType {
26
+ self = primitiveCType
27
+ return
26
28
}
27
29
28
30
throw CDeclToCLoweringError . invalidNominalType ( nominalType. nominalTypeDecl)
@@ -33,29 +35,59 @@ extension SwiftStandardLibraryTypes {
33
35
throw CDeclToCLoweringError . invalidFunctionConvention ( functionType)
34
36
35
37
case . c:
36
- let resultType = try cdeclToCLowering ( functionType. resultType)
38
+ let resultType = try CType ( cdeclType : functionType. resultType)
37
39
let parameterTypes = try functionType. parameters. map { param in
38
- try cdeclToCLowering ( param. type)
40
+ try CType ( cdeclType : param. type)
39
41
}
40
42
41
- return . function(
43
+ self = . function(
42
44
resultType: resultType,
43
45
parameters: parameterTypes,
44
46
variadic: false
45
47
)
46
48
}
47
49
48
50
case . tuple( [ ] ) :
49
- return . void
51
+ self = . void
50
52
51
53
case . metatype, . optional, . tuple:
52
- throw CDeclToCLoweringError . invalidCDeclType ( swiftType )
54
+ throw CDeclToCLoweringError . invalidCDeclType ( cdeclType )
53
55
}
54
56
}
55
57
}
56
58
59
+ extension CFunction {
60
+ /// Produce a C function that represents the given @_cdecl Swift function.
61
+ init ( cdeclSignature: SwiftFunctionSignature , cName: String ) throws {
62
+ assert ( cdeclSignature. selfParameter == nil )
63
+
64
+ let cResultType = try CType ( cdeclType: cdeclSignature. result. type)
65
+ let cParameters = try cdeclSignature. parameters. map { parameter in
66
+ CParameter (
67
+ name: parameter. parameterName,
68
+ type: try CType ( cdeclType: parameter. type) . parameterDecay
69
+ )
70
+ }
71
+
72
+ self = CFunction (
73
+ resultType: cResultType,
74
+ name: cName,
75
+ parameters: cParameters,
76
+ isVariadic: false
77
+ )
78
+ }
79
+ }
80
+
81
+ enum CDeclToCLoweringError : Error {
82
+ case invalidCDeclType( SwiftType )
83
+ case invalidNominalType( SwiftNominalTypeDeclaration )
84
+ case invalidFunctionConvention( SwiftFunctionType )
85
+ }
86
+
57
87
extension KnownStandardLibraryType {
58
- func loweredCType( ) throws -> CType {
88
+ /// Determine the primitive C type that corresponds to this C standard
89
+ /// library type, if there is one.
90
+ var primitiveCType : CType ? {
59
91
switch self {
60
92
case . bool: . integral( . bool)
61
93
case . int: . integral( . ptrdiff_t)
@@ -74,12 +106,8 @@ extension KnownStandardLibraryType {
74
106
case . unsafeRawPointer: . pointer(
75
107
. qualified( const: true , volatile: false , type: . void)
76
108
)
109
+ case . unsafePointer, . unsafeMutablePointer, . unsafeBufferPointer, . unsafeMutableBufferPointer:
110
+ nil
77
111
}
78
112
}
79
113
}
80
- enum CDeclToCLoweringError : Error {
81
- case invalidCDeclType( SwiftType )
82
- case invalidNominalType( SwiftNominalTypeDeclaration )
83
- case invalidFunctionConvention( SwiftFunctionType )
84
- }
85
-
0 commit comments