Skip to content

Commit 627e232

Browse files
committed
Read tuple labels in MetadataReader and preserve them in RemoteAST.
The metadata system doesn't actually unique based on labels correctly, so the test case has to play some games. That's something that will be easier to fix when there are fewer clients poking at the internals of the metadata runtime.
1 parent 729428b commit 627e232

File tree

4 files changed

+76
-25
lines changed

4 files changed

+76
-25
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class TypeRefBuilder {
138138

139139
const TupleTypeRef *
140140
createTupleType(const std::vector<const TypeRef *> &elements,
141-
bool isVariadic) {
141+
std::string &&labels, bool isVariadic) {
142142
return TupleTypeRef::create(*this, elements, isVariadic);
143143
}
144144

include/swift/Remote/MetadataReader.h

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,39 @@ class TypeDecoder {
172172
return decodeMangledType(Node->getChild(0));
173173
case NodeKind::NonVariadicTuple:
174174
case NodeKind::VariadicTuple: {
175-
std::vector<BuiltType> Elements;
176-
for (auto element : *Node) {
177-
auto elementType = decodeMangledType(element);
175+
std::vector<BuiltType> elements;
176+
std::string labels;
177+
for (auto &element : *Node) {
178+
if (element->getKind() != NodeKind::TupleElement)
179+
return BuiltType();
180+
181+
// If the tuple element is labelled, add its label to 'labels'.
182+
unsigned typeChildIndex = 0;
183+
if (element->getChild(0)->getKind() == NodeKind::TupleElementName) {
184+
// Add spaces to terminate all the previous labels if this
185+
// is the first we've seen.
186+
if (labels.empty()) labels.append(elements.size(), ' ');
187+
188+
// Add the label and its terminator.
189+
labels += element->getChild(0)->getText();
190+
labels += ' ';
191+
typeChildIndex = 1;
192+
193+
// Otherwise, add a space if a previous element had a label.
194+
} else if (!labels.empty()) {
195+
labels += ' ';
196+
}
197+
198+
// Decode the element type.
199+
BuiltType elementType =
200+
decodeMangledType(element->getChild(typeChildIndex));
178201
if (!elementType)
179202
return BuiltType();
180-
Elements.push_back(elementType);
203+
204+
elements.push_back(elementType);
181205
}
182-
bool Variadic = (Node->getKind() == NodeKind::VariadicTuple);
183-
return Builder.createTupleType(Elements, Variadic);
206+
bool variadic = (Node->getKind() == NodeKind::VariadicTuple);
207+
return Builder.createTupleType(elements, std::move(labels), variadic);
184208
}
185209
case NodeKind::TupleElement:
186210
if (Node->getChild(0)->getKind() == NodeKind::TupleElementName)
@@ -459,24 +483,35 @@ class MetadataReader {
459483
case MetadataKind::Optional:
460484
return readNominalTypeFromMetadata(Meta);
461485
case MetadataKind::Tuple: {
462-
auto TupleMeta = cast<TargetTupleTypeMetadata<Runtime>>(Meta);
463-
std::vector<BuiltType> Elements;
464-
StoredPointer ElementAddress = MetadataAddress +
486+
auto tupleMeta = cast<TargetTupleTypeMetadata<Runtime>>(Meta);
487+
488+
std::vector<BuiltType> elementTypes;
489+
elementTypes.reserve(tupleMeta->NumElements);
490+
491+
StoredPointer elementAddress = MetadataAddress +
465492
sizeof(TargetTupleTypeMetadata<Runtime>);
466493
using Element = typename TargetTupleTypeMetadata<Runtime>::Element;
467-
for (StoredPointer i = 0; i < TupleMeta->NumElements; ++i,
468-
ElementAddress += sizeof(Element)) {
469-
Element E;
470-
if (!Reader->readBytes(RemoteAddress(ElementAddress),
471-
(uint8_t*)&E, sizeof(Element)))
494+
for (StoredPointer i = 0; i < tupleMeta->NumElements; ++i,
495+
elementAddress += sizeof(Element)) {
496+
Element element;
497+
if (!Reader->readBytes(RemoteAddress(elementAddress),
498+
(uint8_t*)&element, sizeof(Element)))
472499
return BuiltType();
473500

474-
if (auto ElementTypeRef = readTypeFromMetadata(E.Type))
475-
Elements.push_back(ElementTypeRef);
501+
if (auto elementType = readTypeFromMetadata(element.Type))
502+
elementTypes.push_back(elementType);
476503
else
477504
return BuiltType();
478505
}
479-
return Builder.createTupleType(Elements, /*variadic*/ false);
506+
507+
// Read the labels string.
508+
std::string labels;
509+
if (tupleMeta->Labels &&
510+
!Reader->readString(RemoteAddress(tupleMeta->Labels), labels))
511+
return BuiltType();
512+
513+
return Builder.createTupleType(elementTypes, std::move(labels),
514+
/*variadic*/ false);
480515
}
481516
case MetadataKind::Function: {
482517
auto Function = cast<TargetFunctionTypeMetadata<Runtime>>(Meta);

lib/RemoteAST/RemoteAST.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,22 @@ class RemoteASTTypeBuilder {
184184
return genericType;
185185
}
186186

187-
Type createTupleType(ArrayRef<Type> eltTypes, bool isVariadic) {
187+
Type createTupleType(ArrayRef<Type> eltTypes, StringRef labels,
188+
bool isVariadic) {
188189
// Just bail out on variadic tuples for now.
189190
if (isVariadic) return Type();
190191

191192
SmallVector<TupleTypeElt, 4> elements;
192193
elements.reserve(eltTypes.size());
193194
for (auto eltType : eltTypes) {
194-
elements.push_back(eltType);
195+
Identifier label;
196+
if (!labels.empty()) {
197+
auto split = labels.split(' ');
198+
if (!split.first.empty())
199+
label = Ctx.getIdentifier(split.first);
200+
labels = split.second;
201+
}
202+
elements.emplace_back(eltType, label);
195203
}
196204

197205
return TupleType::get(elements, Ctx);

test/RemoteAST/structural_types.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,26 @@ func printType(_: Any.Type)
55

66
typealias Fn1 = () -> ()
77
printType(Fn1.self)
8-
// CHECK: () -> ()
8+
// CHECK: found type: () -> ()
99

1010
typealias Fn2 = (Int, Float) -> ()
1111
printType(Fn2.self)
12-
// CHECK: (Int, Float) -> ()
12+
// CHECK: found type: (Int, Float) -> ()
1313

1414
typealias Tuple1 = (Int, Float, Int)
1515
printType(Tuple1.self)
16-
// CHECK: (Int, Float, Int)
16+
// CHECK: found type: (Int, Float, Int)
1717

1818
printType(Int.Type.self)
19-
// CHECK: Int.Type
19+
// CHECK: found type: Int.Type
2020

2121
printType(Tuple1.Type.self)
22-
// CHECK: (Int, Float, Int).Type
22+
// CHECK: found type: (Int, Float, Int).Type
23+
24+
typealias Tuple2 = (Int.Type, x: Float, Int)
25+
printType(Tuple2.self)
26+
// CHECK: found type: (Int.Type, x: Float, Int)
27+
28+
typealias Tuple3 = (x: Int, Float, y: Int.Type)
29+
printType(Tuple3.self)
30+
// CHECK: found type: (x: Int, Float, y: Int.Type)

0 commit comments

Comments
 (0)