Skip to content

Commit 83fd37a

Browse files
committed
[Runtime] Form function types based on mangled names.
Fixes some issues in the type decoder with function flags not getting set when forming function types.
1 parent 7148e84 commit 83fd37a

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

include/swift/Demangling/TypeDecoder.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,15 @@ class TypeDecoder {
255255

256256
bool isThrow =
257257
Node->getChild(0)->getKind() == NodeKind::ThrowsAnnotation;
258-
flags = flags.withThrows(true);
258+
flags = flags.withThrows(isThrow);
259259

260+
bool hasParamFlags = false;
260261
std::vector<FunctionParam<BuiltType>> parameters;
261262
if (!decodeMangledFunctionInputType(Node->getChild(isThrow ? 1 : 0),
262-
parameters))
263+
parameters, hasParamFlags))
263264
return BuiltType();
265+
flags = flags.withNumParameters(parameters.size())
266+
.withParameterFlags(hasParamFlags);
264267

265268
auto result = decodeMangledType(Node->getChild(isThrow ? 2 : 1));
266269
if (!result) return BuiltType();
@@ -435,11 +438,13 @@ class TypeDecoder {
435438

436439
bool decodeMangledFunctionInputType(
437440
const Demangle::NodePointer &node,
438-
std::vector<FunctionParam<BuiltType>> &params) {
441+
std::vector<FunctionParam<BuiltType>> &params,
442+
bool &hasParamFlags) {
439443
// Look through a couple of sugar nodes.
440444
if (node->getKind() == NodeKind::Type ||
441445
node->getKind() == NodeKind::ArgumentTuple) {
442-
return decodeMangledFunctionInputType(node->getFirstChild(), params);
446+
return decodeMangledFunctionInputType(node->getFirstChild(), params,
447+
hasParamFlags);
443448
}
444449

445450
auto decodeParamTypeAndFlags =
@@ -450,10 +455,12 @@ class TypeDecoder {
450455
case NodeKind::InOut:
451456
param.setInOut();
452457
node = node->getFirstChild();
458+
hasParamFlags = true;
453459
break;
454460

455461
case NodeKind::Shared:
456462
param.setShared();
463+
hasParamFlags = true;
457464
node = node->getFirstChild();
458465
break;
459466

@@ -483,6 +490,7 @@ class TypeDecoder {
483490

484491
case NodeKind::VariadicMarker:
485492
param.setVariadic();
493+
hasParamFlags = true;
486494
break;
487495

488496
case NodeKind::Type:

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,24 @@ class DecodedMetadataBuilder {
313313
BuiltType createFunctionType(
314314
ArrayRef<Demangle::FunctionParam<BuiltType>> params,
315315
BuiltType result, FunctionTypeFlags flags) const {
316-
// FIXME: Implement.
317-
return BuiltType();
316+
std::vector<BuiltType> paramTypes;
317+
std::vector<uint32_t> paramFlags;
318+
319+
// Fill in the parameters.
320+
paramTypes.reserve(params.size());
321+
if (flags.hasParameterFlags())
322+
paramFlags.reserve(params.size());
323+
for (const auto &param : params) {
324+
paramTypes.push_back(param.getType());
325+
if (flags.hasParameterFlags())
326+
paramFlags.push_back(param.getFlags().getIntValue());
327+
}
328+
329+
return swift_getFunctionTypeMetadata(flags, paramTypes.data(),
330+
flags.hasParameterFlags()
331+
? paramFlags.data()
332+
: nullptr,
333+
result);
318334
}
319335

320336
BuiltType createTupleType(ArrayRef<BuiltType> elements,

test/Runtime/demangleToMetadata.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,52 @@ DemangleToMetadataTests.test("tuple types") {
1818
expectEqual(type(of: (a: (), b: ())), _typeByMangledName("yt1a_yt1bt")!)
1919
}
2020

21+
func f0() { }
22+
var f0_thin: @convention(thin) () -> Void = f0
23+
var f0_c: @convention(c) () -> Void = f0
24+
25+
#if _runtime(_ObjC)
26+
var f0_block: @convention(block) () -> Void = f0
27+
#endif
28+
29+
func f0_throws() throws { }
30+
31+
func f1(x: ()) { }
32+
func f2(x: (), y: ()) { }
33+
34+
func f1_variadic(x: ()...) { }
35+
func f1_inout(x: inout ()) { }
36+
37+
func f2_variadic_inout(x: ()..., y: inout ()) { }
38+
39+
DemangleToMetadataTests.test("function types") {
40+
// Conventions
41+
expectEqual(type(of: f0), _typeByMangledName("yyc")!)
42+
expectEqual(type(of: f0_thin), _typeByMangledName("yyXf")!)
43+
expectEqual(type(of: f0_c), _typeByMangledName("yyXC")!)
44+
#if _runtime(_ObjC)
45+
expectEqual(type(of: f0_block), _typeByMangledName("yyXB")!)
46+
#endif
47+
48+
// Throwing functions
49+
expectEqual(type(of: f0_throws), _typeByMangledName("yyKc")!)
50+
51+
// More parameters.
52+
expectEqual(type(of: f1), _typeByMangledName("yyyt_tc")!)
53+
expectEqual(type(of: f2), _typeByMangledName("yyyt_yttc")!)
54+
55+
// Variadic parameters.
56+
expectEqual(type(of: f1_variadic), _typeByMangledName("yyytd_tc")!)
57+
58+
// Inout parameters.
59+
expectEqual(type(of: f1_inout), _typeByMangledName("yyytzc")!)
60+
61+
// Ownership parameters.
62+
// FIXME: Shared/owned
63+
64+
// Mix-and-match.
65+
expectEqual(type(of: f2_variadic_inout), _typeByMangledName("yyytd_ytztc")!)
66+
}
67+
2168
runAllTests()
2269

0 commit comments

Comments
 (0)