Skip to content

Commit 830bd75

Browse files
authored
Merge pull request #67124 from slavapestov/runtime-pack-expansion-demangling
Runtime demangler support for pack expansions
2 parents 823f008 + f303207 commit 830bd75

File tree

13 files changed

+395
-194
lines changed

13 files changed

+395
-194
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,20 @@ class ASTBuilder {
6464
/// is a pack or not, so we have to find it here.
6565
GenericSignature GenericSig;
6666

67+
/// This builder doesn't perform "on the fly" substitutions, so we preserve
68+
/// all pack expansions. We still need an active expansion stack though,
69+
/// for the dummy implementation of these methods:
70+
/// - beginPackExpansion()
71+
/// - advancePackExpansion()
72+
/// - createExpandedPackElement()
73+
/// - endPackExpansion()
74+
llvm::SmallVector<Type> ActivePackExpansions;
75+
6776
public:
6877
using BuiltType = swift::Type;
6978
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
7079
using BuiltProtocolDecl = swift::ProtocolDecl *;
7180
using BuiltGenericSignature = swift::GenericSignature;
72-
using BuiltGenericTypeParam = swift::GenericTypeParamType *;
7381
using BuiltRequirement = swift::Requirement;
7482
using BuiltSubstitutionMap = swift::SubstitutionMap;
7583

@@ -110,13 +118,19 @@ class ASTBuilder {
110118
Type createBoundGenericType(GenericTypeDecl *decl, ArrayRef<Type> args,
111119
Type parent);
112120

113-
Type createTupleType(ArrayRef<Type> eltTypes, StringRef labels);
121+
Type createTupleType(ArrayRef<Type> eltTypes, ArrayRef<StringRef> labels);
114122

115123
Type createPackType(ArrayRef<Type> eltTypes);
116124

117125
Type createSILPackType(ArrayRef<Type> eltTypes, bool isElementAddress);
118126

119-
Type createPackExpansionType(Type patternType, Type countType);
127+
size_t beginPackExpansion(Type countType);
128+
129+
void advancePackExpansion(size_t index);
130+
131+
Type createExpandedPackElement(Type patternType);
132+
133+
void endPackExpansion();
120134

121135
Type createFunctionType(
122136
ArrayRef<Demangle::FunctionParam<Type>> params,

include/swift/Demangling/TypeDecoder.h

Lines changed: 116 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,6 @@ class TypeDecoder {
478478
using BuiltSubstitution = typename BuilderType::BuiltSubstitution;
479479
using BuiltRequirement = typename BuilderType::BuiltRequirement;
480480
using BuiltLayoutConstraint = typename BuilderType::BuiltLayoutConstraint;
481-
using BuiltGenericTypeParam = typename BuilderType::BuiltGenericTypeParam;
482481
using BuiltGenericSignature = typename BuilderType::BuiltGenericSignature;
483482
using BuiltSubstitutionMap = typename BuilderType::BuiltSubstitutionMap;
484483
using NodeKind = Demangle::Node::Kind;
@@ -886,10 +885,11 @@ class TypeDecoder {
886885

887886
bool hasParamFlags = false;
888887
llvm::SmallVector<FunctionParam<BuiltType>, 8> parameters;
889-
if (!decodeMangledFunctionInputType(Node->getChild(firstChildIdx),
890-
depth + 1, parameters, hasParamFlags))
891-
return MAKE_NODE_TYPE_ERROR0(Node->getChild(firstChildIdx),
892-
"failed to decode function type");
888+
auto optError = decodeMangledFunctionInputType(Node->getChild(firstChildIdx),
889+
depth + 1, parameters, hasParamFlags);
890+
if (optError)
891+
return *optError;
892+
893893
flags =
894894
flags.withNumParameters(parameters.size())
895895
.withParameterFlags(hasParamFlags)
@@ -1022,7 +1022,8 @@ class TypeDecoder {
10221022

10231023
case NodeKind::Tuple: {
10241024
llvm::SmallVector<BuiltType, 8> elements;
1025-
std::string labels;
1025+
llvm::SmallVector<StringRef, 8> labels;
1026+
10261027
for (auto &element : *Node) {
10271028
if (element->getKind() != NodeKind::TupleElement)
10281029
return MAKE_NODE_TYPE_ERROR0(Node, "unexpected kind");
@@ -1033,31 +1034,32 @@ class TypeDecoder {
10331034
return MAKE_NODE_TYPE_ERROR0(element->getChild(typeChildIndex),
10341035
"no children");
10351036
}
1036-
if (element->getChild(typeChildIndex)->getKind() == NodeKind::TupleElementName) {
1037-
// Add spaces to terminate all the previous labels if this
1038-
// is the first we've seen.
1039-
if (labels.empty()) labels.append(elements.size(), ' ');
10401037

1041-
// Add the label and its terminator.
1042-
labels += element->getChild(typeChildIndex)->getText();
1043-
labels += ' ';
1038+
StringRef label;
1039+
if (element->getChild(typeChildIndex)->getKind() == NodeKind::TupleElementName) {
1040+
label = element->getChild(typeChildIndex)->getText();
10441041
typeChildIndex++;
1045-
1046-
// Otherwise, add a space if a previous element had a label.
1047-
} else if (!labels.empty()) {
1048-
labels += ' ';
10491042
}
10501043

10511044
// Decode the element type.
1052-
auto elementType =
1053-
decodeMangledType(element->getChild(typeChildIndex), depth + 1,
1054-
/*forRequirement=*/false);
1055-
if (elementType.isError())
1056-
return elementType;
1057-
1058-
elements.push_back(elementType.getType());
1045+
auto optError = decodeTypeSequenceElement(
1046+
element->getChild(typeChildIndex), depth + 1,
1047+
[&](BuiltType type) {
1048+
elements.push_back(type);
1049+
labels.push_back(label);
1050+
});
1051+
if (optError)
1052+
return *optError;
10591053
}
1060-
return Builder.createTupleType(elements, std::move(labels));
1054+
1055+
// Unwrap one-element tuples.
1056+
//
1057+
// FIXME: The behavior of one-element labeled tuples is inconsistent throughout
1058+
// the different re-implementations of type substitution and pack expansion.
1059+
// if (elements.size() == 1)
1060+
// return elements[0];
1061+
1062+
return Builder.createTupleType(elements, labels);
10611063
}
10621064
case NodeKind::TupleElement:
10631065
if (Node->getNumChildren() < 1)
@@ -1082,12 +1084,13 @@ class TypeDecoder {
10821084

10831085
for (auto &element : *Node) {
10841086
// Decode the element type.
1085-
auto elementType =
1086-
decodeMangledType(element, depth + 1, /*forRequirement=*/false);
1087-
if (elementType.isError())
1088-
return elementType;
1089-
1090-
elements.push_back(elementType.getType());
1087+
auto optError = decodeTypeSequenceElement(
1088+
element, depth + 1,
1089+
[&](BuiltType elementType) {
1090+
elements.push_back(elementType);
1091+
});
1092+
if (optError)
1093+
return *optError;
10911094
}
10921095

10931096
switch (Node->getKind()) {
@@ -1103,16 +1106,8 @@ class TypeDecoder {
11031106
}
11041107

11051108
case NodeKind::PackExpansion: {
1106-
if (Node->getNumChildren() < 2)
1107-
return MAKE_NODE_TYPE_ERROR(Node,
1108-
"fewer children (%zu) than required (2)",
1109-
Node->getNumChildren());
1110-
1111-
auto patternType = decodeMangledType(Node->getChild(0), depth + 1);
1112-
auto countType = decodeMangledType(Node->getChild(1), depth + 1);
1113-
1114-
return Builder.createPackExpansionType(patternType.getType(),
1115-
countType.getType());
1109+
return MAKE_NODE_TYPE_ERROR0(Node,
1110+
"pack expansion type in unsupported position");
11161111
}
11171112

11181113
case NodeKind::DependentGenericType: {
@@ -1264,9 +1259,9 @@ return {}; // Not Implemented!
12641259
/*forRequirement=*/false);
12651260
if (substTy.isError())
12661261
return substTy;
1267-
substitutions.emplace_back(
1268-
Builder.createGenericTypeParameterType(paramDepth, index),
1269-
substTy.getType());
1262+
auto paramTy = Builder.createGenericTypeParameterType(
1263+
paramDepth, index);
1264+
substitutions.emplace_back(paramTy, substTy.getType());
12701265
++index;
12711266
}
12721267
}
@@ -1369,6 +1364,58 @@ return {}; // Not Implemented!
13691364
}
13701365

13711366
private:
1367+
template<typename Fn>
1368+
llvm::Optional<TypeLookupError>
1369+
decodeTypeSequenceElement(Demangle::NodePointer node, unsigned depth,
1370+
Fn resultCallback) {
1371+
if (node->getKind() == NodeKind::Type)
1372+
node = node->getChild(0);
1373+
1374+
if (node->getKind() == NodeKind::PackExpansion) {
1375+
if (node->getNumChildren() < 2)
1376+
return MAKE_NODE_TYPE_ERROR(node,
1377+
"fewer children (%zu) than required (2)",
1378+
node->getNumChildren());
1379+
1380+
auto patternType = node->getChild(0);
1381+
1382+
// Decode the shape pack first, to form a metadata pack.
1383+
auto countType = decodeMangledType(node->getChild(1), depth);
1384+
if (countType.isError())
1385+
return *countType.getError();
1386+
1387+
// Push the pack expansion on the active expansion stack inside the
1388+
// builder concept.
1389+
size_t numElements = Builder.beginPackExpansion(countType.getType());
1390+
1391+
for (size_t i = 0; i < numElements; ++i) {
1392+
// Advance the lane index inside the builder concept.
1393+
Builder.advancePackExpansion(i);
1394+
1395+
// Decode the pattern type, taking the ith element of each pack
1396+
// referenced therein.
1397+
auto expandedElementType = decodeMangledType(patternType, depth);
1398+
if (expandedElementType.isError())
1399+
return *expandedElementType.getError();
1400+
1401+
resultCallback(Builder.createExpandedPackElement(
1402+
expandedElementType.getType()));
1403+
}
1404+
1405+
// Pop the active expansion stack inside the builder concept.
1406+
Builder.endPackExpansion();
1407+
} else {
1408+
auto elementType =
1409+
decodeMangledType(node, depth, /*forRequirement=*/false);
1410+
if (elementType.isError())
1411+
return *elementType.getError();
1412+
1413+
resultCallback(elementType.getType());
1414+
}
1415+
1416+
return llvm::None;
1417+
}
1418+
13721419
template <typename T>
13731420
bool decodeImplFunctionPart(Demangle::NodePointer node, unsigned depth,
13741421
llvm::SmallVectorImpl<T> &results) {
@@ -1532,12 +1579,12 @@ return {}; // Not Implemented!
15321579
return Builder.createProtocolDecl(node);
15331580
}
15341581

1535-
bool decodeMangledFunctionInputType(
1582+
llvm::Optional<TypeLookupError> decodeMangledFunctionInputType(
15361583
Demangle::NodePointer node, unsigned depth,
15371584
llvm::SmallVectorImpl<FunctionParam<BuiltType>> &params,
15381585
bool &hasParamFlags) {
15391586
if (depth > TypeDecoder::MaxDepth)
1540-
return false;
1587+
return llvm::None;
15411588

15421589
// Look through a couple of sugar nodes.
15431590
if (node->getKind() == NodeKind::Type ||
@@ -1548,7 +1595,7 @@ return {}; // Not Implemented!
15481595

15491596
auto decodeParamTypeAndFlags =
15501597
[&](Demangle::NodePointer typeNode,
1551-
FunctionParam<BuiltType> &param) -> bool {
1598+
FunctionParam<BuiltType> &param) -> llvm::Optional<TypeLookupError> {
15521599
Demangle::NodePointer node = typeNode;
15531600

15541601
bool recurse = true;
@@ -1597,17 +1644,15 @@ return {}; // Not Implemented!
15971644
}
15981645
}
15991646

1600-
auto paramType = decodeMangledType(node, depth + 1,
1601-
/*forRequirement=*/false);
1602-
if (paramType.isError())
1603-
return false;
1604-
1605-
param.setType(paramType.getType());
1606-
return true;
1647+
return decodeTypeSequenceElement(node, depth + 1,
1648+
[&](BuiltType paramType) {
1649+
param.setType(paramType);
1650+
params.push_back(param);
1651+
});
16071652
};
16081653

16091654
auto decodeParam =
1610-
[&](NodePointer paramNode) -> llvm::Optional<FunctionParam<BuiltType>> {
1655+
[&](NodePointer paramNode) -> llvm::Optional<TypeLookupError> {
16111656
if (paramNode->getKind() != NodeKind::TupleElement)
16121657
return llvm::None;
16131658

@@ -1623,40 +1668,41 @@ return {}; // Not Implemented!
16231668
hasParamFlags = true;
16241669
break;
16251670

1626-
case NodeKind::Type:
1627-
if (!decodeParamTypeAndFlags(child->getFirstChild(), param))
1628-
return llvm::None;
1671+
case NodeKind::Type: {
1672+
auto optError = decodeParamTypeAndFlags(
1673+
child->getFirstChild(), param);
1674+
if (optError)
1675+
return optError;
16291676
break;
1677+
}
16301678

16311679
default:
1632-
return llvm::None;
1680+
return TYPE_LOOKUP_ERROR_FMT("unknown node");
16331681
}
16341682
}
16351683

1636-
return param;
1684+
return llvm::None;
16371685
};
16381686

16391687
// Expand a single level of tuple.
16401688
if (node->getKind() == NodeKind::Tuple) {
16411689
// Decode all the elements as separate arguments.
16421690
for (const auto &elt : *node) {
1643-
auto param = decodeParam(elt);
1644-
if (!param)
1645-
return false;
1646-
1647-
params.push_back(std::move(*param));
1691+
auto optError = decodeParam(elt);
1692+
if (optError)
1693+
return *optError;
16481694
}
16491695

1650-
return true;
1696+
return llvm::None;
16511697
}
16521698

16531699
// Otherwise, handle the type as a single argument.
16541700
FunctionParam<BuiltType> param;
1655-
if (!decodeParamTypeAndFlags(node, param))
1656-
return false;
1701+
auto optError = decodeParamTypeAndFlags(node, param);
1702+
if (optError)
1703+
return *optError;
16571704

1658-
params.push_back(std::move(param));
1659-
return true;
1705+
return llvm::None;
16601706
}
16611707
};
16621708

include/swift/Remote/MetadataReader.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ class MetadataReader {
179179
using BuiltRequirement = typename BuilderType::BuiltRequirement;
180180
using BuiltSubstitution = typename BuilderType::BuiltSubstitution;
181181
using BuiltSubstitutionMap = typename BuilderType::BuiltSubstitutionMap;
182-
using BuiltGenericTypeParam = typename BuilderType::BuiltGenericTypeParam;
183182
using BuiltGenericSignature = typename BuilderType::BuiltGenericSignature;
184183
using StoredPointer = typename Runtime::StoredPointer;
185184
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
@@ -871,13 +870,26 @@ class MetadataReader {
871870
}
872871

873872
// Read the labels string.
874-
std::string labels;
873+
std::string labelStr;
875874
if (tupleMeta->Labels &&
876-
!Reader->readString(RemoteAddress(tupleMeta->Labels), labels))
875+
!Reader->readString(RemoteAddress(tupleMeta->Labels), labelStr))
877876
return BuiltType();
878877

878+
std::vector<llvm::StringRef> labels;
879+
std::string::size_type end, start = 0;
880+
while (true) {
881+
end = labelStr.find(' ', start);
882+
if (end == std::string::npos)
883+
break;
884+
labels.push_back(llvm::StringRef(labelStr.data() + start, end - start));
885+
start = end + 1;
886+
}
887+
// Pad the vector with empty labels.
888+
for (unsigned i = labels.size(); i < elementTypes.size(); ++i)
889+
labels.push_back(StringRef());
890+
879891
auto BuiltTuple =
880-
Builder.createTupleType(elementTypes, std::move(labels));
892+
Builder.createTupleType(elementTypes, labels);
881893
TypeCache[MetadataAddress] = BuiltTuple;
882894
return BuiltTuple;
883895
}

0 commit comments

Comments
 (0)