Skip to content

Commit 621b970

Browse files
committed
[ABI/Metadata] Add @autoclosure to function parameter flags
Add `@autoclosure` to parameter flags associated with function type metadata, which makes it possible to correctly round-trip mangled name <-> metadata of function types which have parameters marked as `@autoclosure`. Resolves: rdar://problem/45489901
1 parent f85d8ae commit 621b970

File tree

7 files changed

+57
-6
lines changed

7 files changed

+57
-6
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,11 @@ using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;
880880

881881
template <typename int_type>
882882
class TargetParameterTypeFlags {
883-
enum : int_type { ValueOwnershipMask = 0x7F, VariadicMask = 0x80 };
883+
enum : int_type {
884+
ValueOwnershipMask = 0x7F,
885+
VariadicMask = 0x80,
886+
AutoClosureMask = 0x100,
887+
};
884888
int_type Data;
885889

886890
constexpr TargetParameterTypeFlags(int_type Data) : Data(Data) {}
@@ -900,8 +904,15 @@ class TargetParameterTypeFlags {
900904
(isVariadic ? VariadicMask : 0));
901905
}
902906

907+
constexpr TargetParameterTypeFlags<int_type>
908+
withAutoClosure(bool isAutoClosure) const {
909+
return TargetParameterTypeFlags<int_type>(
910+
(Data & ~AutoClosureMask) | (isAutoClosure ? AutoClosureMask : 0));
911+
}
912+
903913
bool isNone() const { return Data == 0; }
904914
bool isVariadic() const { return Data & VariadicMask; }
915+
bool isAutoClosure() const { return Data & AutoClosureMask; }
905916

906917
ValueOwnership getValueOwnership() const {
907918
return (ValueOwnership)(Data & ValueOwnershipMask);

include/swift/AST/Types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,12 @@ class ParameterTypeFlags {
17261726
| ParameterFlags(uint8_t(ownership) << OwnershipShift);
17271727
}
17281728

1729+
ParameterTypeFlags withAutoClosure(bool isAutoClosure) const {
1730+
return ParameterTypeFlags(isAutoClosure
1731+
? value | ParameterTypeFlags::AutoClosure
1732+
: value - ParameterTypeFlags::AutoClosure);
1733+
}
1734+
17291735
bool operator ==(const ParameterTypeFlags &other) const {
17301736
return value.toRaw() == other.value.toRaw();
17311737
}

include/swift/Demangling/TypeDecoder.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class FunctionParam {
5656
void setType(BuiltType type) { Type = type; }
5757

5858
void setVariadic() { Flags = Flags.withVariadic(true); }
59+
void setAutoClosure() { Flags = Flags.withAutoClosure(true); }
5960
void setValueOwnership(ValueOwnership ownership) {
6061
Flags = Flags.withValueOwnership(ownership);
6162
}
@@ -252,7 +253,6 @@ class TypeDecoder {
252253
if (Node->getNumChildren() < 2)
253254
return BuiltType();
254255

255-
// FIXME: autoclosure is not represented in function metadata
256256
FunctionTypeFlags flags;
257257
if (Node->getKind() == NodeKind::ObjCBlock) {
258258
flags = flags.withConvention(FunctionMetadataConvention::Block);
@@ -564,6 +564,13 @@ class TypeDecoder {
564564
setOwnership(ValueOwnership::Owned);
565565
break;
566566

567+
case NodeKind::AutoClosureType:
568+
case NodeKind::EscapingAutoClosureType: {
569+
param.setAutoClosure();
570+
hasParamFlags = true;
571+
break;
572+
}
573+
567574
default:
568575
break;
569576
}

lib/IRGen/MetadataRequest.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -928,8 +928,9 @@ namespace {
928928
// flags.
929929
auto getABIParameterFlags = [](ParameterTypeFlags flags) {
930930
return ParameterFlags()
931-
.withValueOwnership(flags.getValueOwnership())
932-
.withVariadic(flags.isVariadic());
931+
.withValueOwnership(flags.getValueOwnership())
932+
.withVariadic(flags.isVariadic())
933+
.withAutoClosure(flags.isAutoClosure());
933934
};
934935

935936
bool hasFlags = false;

lib/RemoteAST/RemoteAST.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@ class RemoteASTTypeBuilder {
365365
auto ownership = flags.getValueOwnership();
366366
auto parameterFlags = ParameterTypeFlags()
367367
.withValueOwnership(ownership)
368-
.withVariadic(flags.isVariadic());
368+
.withVariadic(flags.isVariadic())
369+
.withAutoClosure(flags.isAutoClosure());
369370

370371
funcParams.push_back(AnyFunctionType::Param(type, label, parameterFlags));
371372
}

test/IRGen/dynamic_cast_functions.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,17 @@ let k: (Int, inout Int) -> Void = { _,_ in }
5555
let l: (inout Int, Float, inout String) -> Void = { _,_,_ in }
5656
let m: (__shared Int, String, inout Float, Double) -> Void = { _,_,_,_ in }
5757
let n: () -> Int = { 42 }
58+
let o: (@autoclosure () -> Int) -> Void = { (x: @autoclosure () -> Int) -> Void in }
59+
let p: (@autoclosure @escaping () -> Int) -> Void = { (x: @autoclosure @escaping () -> Int) -> Void in }
5860

5961
let i_any: Any = i
6062
let j_any: Any = j
6163
let k_any: Any = k
6264
let l_any: Any = l
6365
let m_any: Any = m
6466
let n_any: Any = n
67+
let o_any: Any = o
68+
let p_any: Any = p
6569

6670
// CHECK: ok
6771
print((i_any as? (Int) -> Void) != nil ? "fail" : "ok")
@@ -125,3 +129,20 @@ print((n_any as? () -> Int) != nil ? "ok" : "fail")
125129
print((n_any as? () -> Void) != nil ? "fail" : "ok")
126130
// CHECK: ok
127131
print((n_any as? (Int) -> Int) != nil ? "fail" : "ok")
132+
133+
// CHECK: ok
134+
print((o_any as? (() -> Int) -> Void) != nil ? "fail" : "ok")
135+
// CHECK: ok
136+
print((o_any as? (inout () -> Int) -> Void) != nil ? "fail" : "ok")
137+
// CHECK: ok
138+
print((o_any as? (@escaping () -> Int) -> Void) != nil ? "fail" : "ok")
139+
// CHECK: ok
140+
print((o_any as? (@autoclosure () -> Int) -> Void) != nil ? "ok" : "fail")
141+
// CHECK: ok
142+
print((o_any as? (@autoclosure @escaping () -> Int) -> Void) != nil ? "fail" : "ok")
143+
// CHECK: ok
144+
print((p_any as? (@escaping () -> Int) -> Void) != nil ? "fail" : "ok")
145+
// CHECK: ok
146+
print((p_any as? (@autoclosure () -> Int) -> Void) != nil ? "fail" : "ok")
147+
// CHECK: ok
148+
print((p_any as? (@autoclosure @escaping () -> Int) -> Void) == nil ? "fail" : "ok")

test/IRGen/function_metadata.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ func test_arch() {
5353
arch({(x: inout Int, y: Double, z: String, w: Int8) -> () in })
5454

5555
// CHECK-LABEL: define{{( protected)?}} linkonce_odr hidden swiftcc %swift.metadata_response @"$syyyccMa"
56-
// CHECK: call %swift.type* @swift_getFunctionTypeMetadata1({{i(32|64)}} 67108865
56+
// CHECK: call %swift.type* @swift_getFunctionTypeMetadata1([[WORD]] 67108865
5757
arch({(x: @escaping () -> ()) -> () in })
58+
59+
// CHECK-LABEL: define{{( protected)?}} linkonce_odr hidden swiftcc %swift.metadata_response @"$sySiyXKcMa"
60+
// CHECK: call %swift.type* @swift_getFunctionTypeMetadata([[WORD]] 100663297
61+
arch({(x: @autoclosure () -> Int) -> Void in })
5862
}

0 commit comments

Comments
 (0)