mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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
This commit is contained in:
@@ -880,7 +880,11 @@ using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;
|
||||
|
||||
template <typename int_type>
|
||||
class TargetParameterTypeFlags {
|
||||
enum : int_type { ValueOwnershipMask = 0x7F, VariadicMask = 0x80 };
|
||||
enum : int_type {
|
||||
ValueOwnershipMask = 0x7F,
|
||||
VariadicMask = 0x80,
|
||||
AutoClosureMask = 0x100,
|
||||
};
|
||||
int_type Data;
|
||||
|
||||
constexpr TargetParameterTypeFlags(int_type Data) : Data(Data) {}
|
||||
@@ -900,8 +904,15 @@ public:
|
||||
(isVariadic ? VariadicMask : 0));
|
||||
}
|
||||
|
||||
constexpr TargetParameterTypeFlags<int_type>
|
||||
withAutoClosure(bool isAutoClosure) const {
|
||||
return TargetParameterTypeFlags<int_type>(
|
||||
(Data & ~AutoClosureMask) | (isAutoClosure ? AutoClosureMask : 0));
|
||||
}
|
||||
|
||||
bool isNone() const { return Data == 0; }
|
||||
bool isVariadic() const { return Data & VariadicMask; }
|
||||
bool isAutoClosure() const { return Data & AutoClosureMask; }
|
||||
|
||||
ValueOwnership getValueOwnership() const {
|
||||
return (ValueOwnership)(Data & ValueOwnershipMask);
|
||||
|
||||
@@ -1726,6 +1726,12 @@ public:
|
||||
| ParameterFlags(uint8_t(ownership) << OwnershipShift);
|
||||
}
|
||||
|
||||
ParameterTypeFlags withAutoClosure(bool isAutoClosure) const {
|
||||
return ParameterTypeFlags(isAutoClosure
|
||||
? value | ParameterTypeFlags::AutoClosure
|
||||
: value - ParameterTypeFlags::AutoClosure);
|
||||
}
|
||||
|
||||
bool operator ==(const ParameterTypeFlags &other) const {
|
||||
return value.toRaw() == other.value.toRaw();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
void setType(BuiltType type) { Type = type; }
|
||||
|
||||
void setVariadic() { Flags = Flags.withVariadic(true); }
|
||||
void setAutoClosure() { Flags = Flags.withAutoClosure(true); }
|
||||
void setValueOwnership(ValueOwnership ownership) {
|
||||
Flags = Flags.withValueOwnership(ownership);
|
||||
}
|
||||
@@ -252,7 +253,6 @@ class TypeDecoder {
|
||||
if (Node->getNumChildren() < 2)
|
||||
return BuiltType();
|
||||
|
||||
// FIXME: autoclosure is not represented in function metadata
|
||||
FunctionTypeFlags flags;
|
||||
if (Node->getKind() == NodeKind::ObjCBlock) {
|
||||
flags = flags.withConvention(FunctionMetadataConvention::Block);
|
||||
@@ -564,6 +564,13 @@ private:
|
||||
setOwnership(ValueOwnership::Owned);
|
||||
break;
|
||||
|
||||
case NodeKind::AutoClosureType:
|
||||
case NodeKind::EscapingAutoClosureType: {
|
||||
param.setAutoClosure();
|
||||
hasParamFlags = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -928,8 +928,9 @@ namespace {
|
||||
// flags.
|
||||
auto getABIParameterFlags = [](ParameterTypeFlags flags) {
|
||||
return ParameterFlags()
|
||||
.withValueOwnership(flags.getValueOwnership())
|
||||
.withVariadic(flags.isVariadic());
|
||||
.withValueOwnership(flags.getValueOwnership())
|
||||
.withVariadic(flags.isVariadic())
|
||||
.withAutoClosure(flags.isAutoClosure());
|
||||
};
|
||||
|
||||
bool hasFlags = false;
|
||||
|
||||
@@ -365,7 +365,8 @@ public:
|
||||
auto ownership = flags.getValueOwnership();
|
||||
auto parameterFlags = ParameterTypeFlags()
|
||||
.withValueOwnership(ownership)
|
||||
.withVariadic(flags.isVariadic());
|
||||
.withVariadic(flags.isVariadic())
|
||||
.withAutoClosure(flags.isAutoClosure());
|
||||
|
||||
funcParams.push_back(AnyFunctionType::Param(type, label, parameterFlags));
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ let k: (Int, inout Int) -> Void = { _,_ in }
|
||||
let l: (inout Int, Float, inout String) -> Void = { _,_,_ in }
|
||||
let m: (__shared Int, String, inout Float, Double) -> Void = { _,_,_,_ in }
|
||||
let n: () -> Int = { 42 }
|
||||
let o: (@autoclosure () -> Int) -> Void = { (x: @autoclosure () -> Int) -> Void in }
|
||||
let p: (@autoclosure @escaping () -> Int) -> Void = { (x: @autoclosure @escaping () -> Int) -> Void in }
|
||||
|
||||
let i_any: Any = i
|
||||
let j_any: Any = j
|
||||
@@ -62,6 +64,8 @@ let k_any: Any = k
|
||||
let l_any: Any = l
|
||||
let m_any: Any = m
|
||||
let n_any: Any = n
|
||||
let o_any: Any = o
|
||||
let p_any: Any = p
|
||||
|
||||
// CHECK: ok
|
||||
print((i_any as? (Int) -> Void) != nil ? "fail" : "ok")
|
||||
@@ -125,3 +129,20 @@ print((n_any as? () -> Int) != nil ? "ok" : "fail")
|
||||
print((n_any as? () -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((n_any as? (Int) -> Int) != nil ? "fail" : "ok")
|
||||
|
||||
// CHECK: ok
|
||||
print((o_any as? (() -> Int) -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((o_any as? (inout () -> Int) -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((o_any as? (@escaping () -> Int) -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((o_any as? (@autoclosure () -> Int) -> Void) != nil ? "ok" : "fail")
|
||||
// CHECK: ok
|
||||
print((o_any as? (@autoclosure @escaping () -> Int) -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((p_any as? (@escaping () -> Int) -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((p_any as? (@autoclosure () -> Int) -> Void) != nil ? "fail" : "ok")
|
||||
// CHECK: ok
|
||||
print((p_any as? (@autoclosure @escaping () -> Int) -> Void) == nil ? "fail" : "ok")
|
||||
|
||||
@@ -53,6 +53,10 @@ func test_arch() {
|
||||
arch({(x: inout Int, y: Double, z: String, w: Int8) -> () in })
|
||||
|
||||
// CHECK-LABEL: define{{( protected)?}} linkonce_odr hidden swiftcc %swift.metadata_response @"$syyyccMa"
|
||||
// CHECK: call %swift.type* @swift_getFunctionTypeMetadata1({{i(32|64)}} 67108865
|
||||
// CHECK: call %swift.type* @swift_getFunctionTypeMetadata1([[WORD]] 67108865
|
||||
arch({(x: @escaping () -> ()) -> () in })
|
||||
|
||||
// CHECK-LABEL: define{{( protected)?}} linkonce_odr hidden swiftcc %swift.metadata_response @"$sySiyXKcMa"
|
||||
// CHECK: call %swift.type* @swift_getFunctionTypeMetadata([[WORD]] 100663297
|
||||
arch({(x: @autoclosure () -> Int) -> Void in })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user