Skip to content

Commit f40a447

Browse files
committed
TypeDecoder: Implement lane-wise pack expansion
1 parent 338cb7c commit f40a447

File tree

6 files changed

+221
-58
lines changed

6 files changed

+221
-58
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 17 additions & 1 deletion
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

@@ -118,6 +126,14 @@ class ASTBuilder {
118126

119127
Type createPackExpansionType(Type patternType, Type countType);
120128

129+
size_t beginPackExpansion(Type countType);
130+
131+
void advancePackExpansion(size_t index);
132+
133+
Type createExpandedPackElement(Type patternType);
134+
135+
void endPackExpansion();
136+
121137
Type createFunctionType(
122138
ArrayRef<Demangle::FunctionParam<Type>> params,
123139
Type output, FunctionTypeFlags flags,

include/swift/Demangling/TypeDecoder.h

Lines changed: 111 additions & 52 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)
@@ -1034,24 +1034,31 @@ class TypeDecoder {
10341034
return MAKE_NODE_TYPE_ERROR0(element->getChild(typeChildIndex),
10351035
"no children");
10361036
}
1037+
1038+
StringRef label;
10371039
if (element->getChild(typeChildIndex)->getKind() == NodeKind::TupleElementName) {
1038-
labels.push_back(element->getChild(typeChildIndex)->getText());
1040+
label = element->getChild(typeChildIndex)->getText();
10391041
typeChildIndex++;
1040-
1041-
// Otherwise, add an empty label.
1042-
} else {
1043-
labels.push_back(StringRef());
10441042
}
10451043

10461044
// Decode the element type.
1047-
auto elementType =
1048-
decodeMangledType(element->getChild(typeChildIndex), depth + 1,
1049-
/*forRequirement=*/false);
1050-
if (elementType.isError())
1051-
return elementType;
1052-
1053-
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;
10541053
}
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+
10551062
return Builder.createTupleType(elements, labels);
10561063
}
10571064
case NodeKind::TupleElement:
@@ -1077,12 +1084,13 @@ class TypeDecoder {
10771084

10781085
for (auto &element : *Node) {
10791086
// Decode the element type.
1080-
auto elementType =
1081-
decodeMangledType(element, depth + 1, /*forRequirement=*/false);
1082-
if (elementType.isError())
1083-
return elementType;
1084-
1085-
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;
10861094
}
10871095

10881096
switch (Node->getKind()) {
@@ -1259,9 +1267,9 @@ return {}; // Not Implemented!
12591267
/*forRequirement=*/false);
12601268
if (substTy.isError())
12611269
return substTy;
1262-
substitutions.emplace_back(
1263-
Builder.createGenericTypeParameterType(paramDepth, index),
1264-
substTy.getType());
1270+
auto paramTy = Builder.createGenericTypeParameterType(
1271+
paramDepth, index);
1272+
substitutions.emplace_back(paramTy, substTy.getType());
12651273
++index;
12661274
}
12671275
}
@@ -1364,6 +1372,58 @@ return {}; // Not Implemented!
13641372
}
13651373

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

1530-
bool decodeMangledFunctionInputType(
1590+
llvm::Optional<TypeLookupError> decodeMangledFunctionInputType(
15311591
Demangle::NodePointer node, unsigned depth,
15321592
llvm::SmallVectorImpl<FunctionParam<BuiltType>> &params,
15331593
bool &hasParamFlags) {
15341594
if (depth > TypeDecoder::MaxDepth)
1535-
return false;
1595+
return llvm::None;
15361596

15371597
// Look through a couple of sugar nodes.
15381598
if (node->getKind() == NodeKind::Type ||
@@ -1543,7 +1603,7 @@ return {}; // Not Implemented!
15431603

15441604
auto decodeParamTypeAndFlags =
15451605
[&](Demangle::NodePointer typeNode,
1546-
FunctionParam<BuiltType> &param) -> bool {
1606+
FunctionParam<BuiltType> &param) -> llvm::Optional<TypeLookupError> {
15471607
Demangle::NodePointer node = typeNode;
15481608

15491609
bool recurse = true;
@@ -1592,17 +1652,15 @@ return {}; // Not Implemented!
15921652
}
15931653
}
15941654

1595-
auto paramType = decodeMangledType(node, depth + 1,
1596-
/*forRequirement=*/false);
1597-
if (paramType.isError())
1598-
return false;
1599-
1600-
param.setType(paramType.getType());
1601-
return true;
1655+
return decodeTypeSequenceElement(node, depth + 1,
1656+
[&](BuiltType paramType) {
1657+
param.setType(paramType);
1658+
params.push_back(param);
1659+
});
16021660
};
16031661

16041662
auto decodeParam =
1605-
[&](NodePointer paramNode) -> llvm::Optional<FunctionParam<BuiltType>> {
1663+
[&](NodePointer paramNode) -> llvm::Optional<TypeLookupError> {
16061664
if (paramNode->getKind() != NodeKind::TupleElement)
16071665
return llvm::None;
16081666

@@ -1618,40 +1676,41 @@ return {}; // Not Implemented!
16181676
hasParamFlags = true;
16191677
break;
16201678

1621-
case NodeKind::Type:
1622-
if (!decodeParamTypeAndFlags(child->getFirstChild(), param))
1623-
return llvm::None;
1679+
case NodeKind::Type: {
1680+
auto optError = decodeParamTypeAndFlags(
1681+
child->getFirstChild(), param);
1682+
if (optError)
1683+
return optError;
16241684
break;
1685+
}
16251686

16261687
default:
1627-
return llvm::None;
1688+
return TYPE_LOOKUP_ERROR_FMT("unknown node");
16281689
}
16291690
}
16301691

1631-
return param;
1692+
return llvm::None;
16321693
};
16331694

16341695
// Expand a single level of tuple.
16351696
if (node->getKind() == NodeKind::Tuple) {
16361697
// Decode all the elements as separate arguments.
16371698
for (const auto &elt : *node) {
1638-
auto param = decodeParam(elt);
1639-
if (!param)
1640-
return false;
1641-
1642-
params.push_back(std::move(*param));
1699+
auto optError = decodeParam(elt);
1700+
if (optError)
1701+
return *optError;
16431702
}
16441703

1645-
return true;
1704+
return llvm::None;
16461705
}
16471706

16481707
// Otherwise, handle the type as a single argument.
16491708
FunctionParam<BuiltType> param;
1650-
if (!decodeParamTypeAndFlags(node, param))
1651-
return false;
1709+
auto optError = decodeParamTypeAndFlags(node, param);
1710+
if (optError)
1711+
return *optError;
16521712

1653-
params.push_back(std::move(param));
1654-
return true;
1713+
return llvm::None;
16551714
}
16561715
};
16571716

include/swift/Remote/MetadataReader.h

Lines changed: 0 additions & 1 deletion
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;

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,24 @@ class TypeRefBuilder {
764764
return nullptr;
765765
}
766766

767+
size_t beginPackExpansion(const TypeRef *countType) {
768+
// FIXME: Remote mirrors support for variadic generics.
769+
return 0;
770+
}
771+
772+
void advancePackExpansion(size_t index) {
773+
// FIXME: Remote mirrors support for variadic generics.
774+
}
775+
776+
const TypeRef *createExpandedPackElement(const TypeRef *patternType) {
777+
// FIXME: Remote mirrors support for variadic generics.
778+
return nullptr;
779+
}
780+
781+
void endPackExpansion() {
782+
// FIXME: Remote mirrors support for variadic generics.
783+
}
784+
767785
const FunctionTypeRef *createFunctionType(
768786
llvm::ArrayRef<remote::FunctionParam<const TypeRef *>> params,
769787
const TypeRef *result, FunctionTypeFlags flags,

lib/AST/ASTDemangler.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,26 @@ Type ASTBuilder::createPackExpansionType(Type patternType, Type countType) {
359359
return PackExpansionType::get(patternType, countType);
360360
}
361361

362+
size_t ASTBuilder::beginPackExpansion(Type countType) {
363+
ActivePackExpansions.push_back(countType);
364+
365+
return 1;
366+
}
367+
368+
void ASTBuilder::advancePackExpansion(size_t index) {
369+
assert(index == 0);
370+
}
371+
372+
Type ASTBuilder::createExpandedPackElement(Type patternType) {
373+
assert(!ActivePackExpansions.empty());
374+
auto countType = ActivePackExpansions.back();
375+
return PackExpansionType::get(patternType, countType);
376+
}
377+
378+
void ASTBuilder::endPackExpansion() {
379+
ActivePackExpansions.pop_back();
380+
}
381+
362382
Type ASTBuilder::createFunctionType(
363383
ArrayRef<Demangle::FunctionParam<Type>> params,
364384
Type output, FunctionTypeFlags flags,
@@ -876,7 +896,7 @@ Type ASTBuilder::createParenType(Type base) {
876896
GenericSignature
877897
ASTBuilder::createGenericSignature(ArrayRef<BuiltType> builtParams,
878898
ArrayRef<BuiltRequirement> requirements) {
879-
std::vector<BuiltGenericTypeParam> params;
899+
std::vector<GenericTypeParamType *> params;
880900
for (auto &param : builtParams) {
881901
auto paramTy = param->getAs<GenericTypeParamType>();
882902
if (!paramTy)

0 commit comments

Comments
 (0)