Skip to content

Commit 6dbdfc8

Browse files
authored
Merge pull request #63911 from slavapestov/more-variadic-mangling
More variadic generics mangling changes
2 parents 9e22d96 + 7a0cd5a commit 6dbdfc8

18 files changed

+223
-66
lines changed

docs/ABI/Mangling.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -887,8 +887,10 @@ now codified into the ABI; the index 0 is therefore reserved.
887887

888888
::
889889

890-
generic-signature ::= requirement* 'l' // one generic parameter
891-
generic-signature ::= requirement* 'r' GENERIC-PARAM-COUNT* 'l'
890+
generic-signature ::= requirement* generic-param-pack-marker* 'l' // one generic parameter
891+
generic-signature ::= requirement* generic-param-pack-marker* 'r' GENERIC-PARAM-COUNT* 'l'
892+
893+
generic-param-pack-marker ::= 'Rv' GENERIC_PARAM-INDEX // generic parameter pack marker
892894

893895
GENERIC-PARAM-COUNT ::= 'z' // zero parameters
894896
GENERIC-PARAM-COUNT ::= INDEX // N+1 parameters
@@ -931,9 +933,11 @@ now codified into the ABI; the index 0 is therefore reserved.
931933
LAYOUT-SIZE ::= INDEX // Size only
932934
LAYOUT-SIZE-AND-ALIGNMENT ::= INDEX INDEX // Size followed by alignment
933935

936+
A generic signature begins with an optional list of requirements.
934937

938+
This is followed by an optional list of generic-param-pack-markers to record
939+
which generic parameters are packs (variadic).
935940

936-
A generic signature begins with an optional list of requirements.
937941
The ``<GENERIC-PARAM-COUNT>`` describes the number of generic parameters at
938942
each depth of the signature. As a special case, no ``<GENERIC-PARAM-COUNT>``
939943
values indicates a single generic parameter at the outermost depth::

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ NODE(DependentGenericParamType)
6363
NODE(DependentGenericSameTypeRequirement)
6464
NODE(DependentGenericSameShapeRequirement)
6565
NODE(DependentGenericLayoutRequirement)
66+
NODE(DependentGenericParamPackMarker)
6667
NODE(DependentGenericSignature)
6768
NODE(DependentGenericType)
6869
NODE(DependentMemberType)

lib/AST/ASTDemangler.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,12 +1011,8 @@ LayoutConstraint ASTBuilder::getLayoutConstraintWithSizeAlign(
10111011
CanGenericSignature ASTBuilder::demangleGenericSignature(
10121012
NominalTypeDecl *nominalDecl,
10131013
NodePointer node) {
1014-
// The type parameters appearing in the signature's requirements are not
1015-
// notionally part of our current generic signature.
1016-
//
1017-
// FIXME: Fix this to support variadic generics.
10181014
llvm::SaveAndRestore<GenericSignature> savedSignature(
1019-
GenericSig, GenericSignature());
1015+
GenericSig, nominalDecl->getGenericSignature());
10201016

10211017
SmallVector<Requirement, 2> requirements;
10221018

lib/AST/ASTMangler.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,7 +2979,7 @@ void ASTMangler::appendRequirement(const Requirement &reqt,
29792979
if (tryMangleTypeSubstitution(DT, sig)) {
29802980
switch (reqt.getKind()) {
29812981
case RequirementKind::SameShape:
2982-
llvm_unreachable("Same-shape requirement not supported here");
2982+
llvm_unreachable("Same-shape requirement with dependent member type?");
29832983
case RequirementKind::Conformance:
29842984
return appendOperator("RQ");
29852985
case RequirementKind::Layout:
@@ -3038,14 +3038,20 @@ void ASTMangler::appendRequirement(const Requirement &reqt,
30383038

30393039
void ASTMangler::appendGenericSignatureParts(
30403040
GenericSignature sig,
3041-
ArrayRef<CanTypeWrapper<GenericTypeParamType>> params,
3041+
ArrayRef<CanGenericTypeParamType> params,
30423042
unsigned initialParamDepth,
30433043
ArrayRef<Requirement> requirements) {
30443044
// Mangle the requirements.
30453045
for (const Requirement &reqt : requirements) {
30463046
appendRequirement(reqt, sig);
30473047
}
30483048

3049+
// Mangle which generic parameters are pack parameters.
3050+
for (auto param : params) {
3051+
if (param->isParameterPack())
3052+
appendOpWithGenericParamIndex("Rv", param);
3053+
}
3054+
30493055
if (params.size() == 1 && params[0]->getDepth() == initialParamDepth)
30503056
return appendOperator("l");
30513057

lib/Demangling/Demangler.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static bool isEntity(Node::Kind kind) {
7676

7777
static bool isRequirement(Node::Kind kind) {
7878
switch (kind) {
79+
case Node::Kind::DependentGenericParamPackMarker:
7980
case Node::Kind::DependentGenericSameTypeRequirement:
8081
case Node::Kind::DependentGenericSameShapeRequirement:
8182
case Node::Kind::DependentGenericLayoutRequirement:
@@ -3788,11 +3789,12 @@ NodePointer Demangler::demangleGenericSignature(bool hasParamCounts) {
37883789
}
37893790

37903791
NodePointer Demangler::demangleGenericRequirement() {
3791-
3792+
37923793
enum { Generic, Assoc, CompoundAssoc, Substitution } TypeKind;
3793-
enum { Protocol, BaseClass, SameType, SameShape, Layout } ConstraintKind;
3794+
enum { Protocol, BaseClass, SameType, SameShape, Layout, PackMarker } ConstraintKind;
37943795

37953796
switch (nextChar()) {
3797+
case 'v': ConstraintKind = PackMarker; TypeKind = Generic; break;
37963798
case 'c': ConstraintKind = BaseClass; TypeKind = Assoc; break;
37973799
case 'C': ConstraintKind = BaseClass; TypeKind = CompoundAssoc; break;
37983800
case 'b': ConstraintKind = BaseClass; TypeKind = Generic; break;
@@ -3832,6 +3834,9 @@ NodePointer Demangler::demangleGenericRequirement() {
38323834
}
38333835

38343836
switch (ConstraintKind) {
3837+
case PackMarker:
3838+
return createWithChild(
3839+
Node::Kind::DependentGenericParamPackMarker, ConstrTy);
38353840
case Protocol:
38363841
return createWithChildren(
38373842
Node::Kind::DependentGenericConformanceRequirement, ConstrTy,

lib/Demangling/NodePrinter.cpp

Lines changed: 89 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class NodePrinter {
368368
case Node::Kind::DefaultAssociatedConformanceAccessor:
369369
case Node::Kind::DependentAssociatedTypeRef:
370370
case Node::Kind::DependentGenericSignature:
371+
case Node::Kind::DependentGenericParamPackMarker:
371372
case Node::Kind::DependentGenericParamCount:
372373
case Node::Kind::DependentGenericConformanceRequirement:
373374
case Node::Kind::DependentGenericLayoutRequirement:
@@ -982,6 +983,92 @@ class NodePrinter {
982983
}
983984
}
984985

986+
void printGenericSignature(NodePointer Node, unsigned depth) {
987+
Printer << '<';
988+
989+
unsigned numChildren = Node->getNumChildren();
990+
991+
unsigned numGenericParams = 0;
992+
for (; numGenericParams < numChildren; ++numGenericParams) {
993+
if (Node->getChild(numGenericParams)->getKind()
994+
!= Node::Kind::DependentGenericParamCount) {
995+
break;
996+
}
997+
}
998+
999+
unsigned firstRequirement = numGenericParams;
1000+
for (; firstRequirement < numChildren; ++firstRequirement) {
1001+
auto child = Node->getChild(firstRequirement);
1002+
if (child->getKind() == Node::Kind::Type)
1003+
child = child->getChild(0);
1004+
if (child->getKind() != Node::Kind::DependentGenericParamPackMarker) {
1005+
break;
1006+
}
1007+
}
1008+
1009+
auto isGenericParamPack = [&](unsigned depth, unsigned index) {
1010+
for (unsigned i = numGenericParams; i < firstRequirement; ++i) {
1011+
auto child = Node->getChild(i);
1012+
if (child->getKind() != Node::Kind::DependentGenericParamPackMarker)
1013+
continue;
1014+
child = child->getChild(0);
1015+
1016+
if (child->getKind() != Node::Kind::Type)
1017+
continue;
1018+
1019+
child = child->getChild(0);
1020+
if (child->getKind() != Node::Kind::DependentGenericParamType)
1021+
continue;
1022+
1023+
if (index == child->getChild(0)->getIndex() &&
1024+
depth == child->getChild(1)->getIndex()) {
1025+
return true;
1026+
}
1027+
}
1028+
1029+
return false;
1030+
};
1031+
1032+
unsigned gpDepth = 0;
1033+
for (; gpDepth < numGenericParams; ++gpDepth) {
1034+
if (gpDepth != 0)
1035+
Printer << "><";
1036+
1037+
unsigned count = Node->getChild(gpDepth)->getIndex();
1038+
for (unsigned index = 0; index < count; ++index) {
1039+
if (index != 0)
1040+
Printer << ", ";
1041+
1042+
// Limit the number of printed generic parameters. In practice this
1043+
// it will never be exceeded. The limit is only important for malformed
1044+
// symbols where count can be really huge.
1045+
if (index >= 128) {
1046+
Printer << "...";
1047+
break;
1048+
}
1049+
1050+
if (isGenericParamPack(gpDepth, index))
1051+
Printer << "each ";
1052+
1053+
// FIXME: Depth won't match when a generic signature applies to a
1054+
// method in generic type context.
1055+
Printer << Options.GenericParameterName(gpDepth, index);
1056+
}
1057+
}
1058+
1059+
if (firstRequirement != numChildren) {
1060+
if (Options.DisplayWhereClauses) {
1061+
Printer << " where ";
1062+
for (unsigned i = firstRequirement; i < numChildren; ++i) {
1063+
if (i > firstRequirement)
1064+
Printer << ", ";
1065+
print(Node->getChild(i), depth + 1);
1066+
}
1067+
}
1068+
}
1069+
Printer << '>';
1070+
}
1071+
9851072
void printFunctionSigSpecializationParams(NodePointer Node, unsigned depth);
9861073

9871074
void printSpecializationPrefix(NodePointer node, StringRef Description,
@@ -2634,49 +2721,11 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
26342721

26352722
case Node::Kind::DependentPseudogenericSignature:
26362723
case Node::Kind::DependentGenericSignature: {
2637-
Printer << '<';
2638-
2639-
unsigned depth = 0;
2640-
unsigned numChildren = Node->getNumChildren();
2641-
for (;
2642-
depth < numChildren
2643-
&& Node->getChild(depth)->getKind()
2644-
== Node::Kind::DependentGenericParamCount;
2645-
++depth) {
2646-
if (depth != 0)
2647-
Printer << "><";
2648-
2649-
unsigned count = Node->getChild(depth)->getIndex();
2650-
for (unsigned index = 0; index < count; ++index) {
2651-
if (index != 0)
2652-
Printer << ", ";
2653-
// Limit the number of printed generic parameters. In practice this
2654-
// it will never be exceeded. The limit is only important for malformed
2655-
// symbols where count can be really huge.
2656-
if (index >= 128) {
2657-
Printer << "...";
2658-
break;
2659-
}
2660-
// FIXME: Depth won't match when a generic signature applies to a
2661-
// method in generic type context.
2662-
Printer << Options.GenericParameterName(depth, index);
2663-
}
2664-
}
2665-
2666-
if (depth != numChildren) {
2667-
if (Options.DisplayWhereClauses) {
2668-
Printer << " where ";
2669-
for (unsigned i = depth; i < numChildren; ++i) {
2670-
if (i > depth)
2671-
Printer << ", ";
2672-
print(Node->getChild(i), depth + 1);
2673-
}
2674-
}
2675-
}
2676-
Printer << '>';
2724+
printGenericSignature(Node, depth);
26772725
return nullptr;
26782726
}
26792727
case Node::Kind::DependentGenericParamCount:
2728+
case Node::Kind::DependentGenericParamPackMarker:
26802729
printer_unreachable("should be printed as a child of a "
26812730
"DependentGenericSignature");
26822731
case Node::Kind::DependentGenericConformanceRequirement: {

lib/Demangling/OldRemangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,11 @@ ManglingError Remangler::mangleDependentPseudogenericSignature(Node *node,
19411941
return mangleDependentGenericSignature(node, depth + 1);
19421942
}
19431943

1944+
ManglingError Remangler::mangleDependentGenericParamPackMarker(Node *node,
1945+
unsigned depth) {
1946+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1947+
}
1948+
19441949
ManglingError Remangler::mangleDependentGenericSignature(Node *node,
19451950
unsigned depth) {
19461951
auto i = node->begin(), e = node->end();

lib/Demangling/Remangler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,15 @@ ManglingError Remangler::mangleDependentGenericSignature(Node *node,
11601160
return ManglingError::Success;
11611161
}
11621162

1163+
ManglingError Remangler::mangleDependentGenericParamPackMarker(Node *node,
1164+
unsigned depth) {
1165+
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
1166+
DEMANGLER_ASSERT(node->getChild(0)->getKind() == Node::Kind::Type, node);
1167+
Buffer << "Rv";
1168+
mangleDependentGenericParamIndex(node->getChild(0)->getChild(0));
1169+
return ManglingError::Success;
1170+
}
1171+
11631172
ManglingError Remangler::mangleDependentGenericType(Node *node,
11641173
unsigned depth) {
11651174
RETURN_IF_ERROR(

lib/IRGen/GenPack.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ llvm::Value *IRGenFunction::emitPackShapeExpression(CanType type) {
161161
if (pair.first > 0) {
162162
auto *constant = llvm::ConstantInt::get(IGM.SizeTy, pair.first);
163163
accumulateSum(*this, pair.second, constant);
164+
} else if (pair.second == nullptr) {
165+
pair.second = llvm::ConstantInt::get(IGM.SizeTy, 0);
164166
}
165167

166168
setScopedLocalTypeData(type, kind, pair.second);

lib/SILGen/SILGenLazyConformance.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
#include "SILGen.h"
1414
#include "swift/AST/Decl.h"
15+
#include "swift/AST/PackConformance.h"
1516
#include "swift/AST/ProtocolConformance.h"
17+
#include "swift/AST/ProtocolConformanceRef.h"
1618
#include "swift/ClangImporter/ClangModule.h"
1719
#include "swift/SIL/SILInstruction.h"
1820
#include "swift/SIL/SILVisitor.h"
@@ -31,6 +33,16 @@ void SILGenModule::useConformance(ProtocolConformanceRef conformanceRef) {
3133
if (conformanceRef.isAbstract())
3234
return;
3335

36+
// Recursively visit pack conformances.
37+
if (conformanceRef.isPack()) {
38+
auto *packConformance = conformanceRef.getPack();
39+
40+
for (auto patternConformanceRef : packConformance->getPatternConformances())
41+
useConformance(patternConformanceRef);
42+
43+
return;
44+
}
45+
3446
auto conformance = conformanceRef.getConcrete();
3547

3648
// Always look through inherited conformances.

test/DebugInfo/variadic-generics-count.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
// REQUIRES: asserts
77

88
public func f1<T...>(ts: repeat each T) {
9-
// CHECK: define {{.*}} @"$s1a2f12tsyxxQp_tlF"(%swift.opaque** {{.*}}, i{{32|64}} [[COUNT1_1:.*]], %swift.type** {{.*}})
9+
// CHECK: define {{.*}} @"$s1a2f12tsyxxQp_tRvzlF"(%swift.opaque** {{.*}}, i{{32|64}} [[COUNT1_1:.*]], %swift.type** {{.*}})
1010
// CHECK-DAG: store i{{32|64}} [[COUNT1_1]], i{{32|64}}* %[[COUNT1_1_A:.*]], align
1111
// CHECK-DAG: call void @llvm.dbg.declare({{.*}}[[COUNT1_1_A]], metadata ![[COUNT1_1_VAR:[0-9]+]], metadata !DIExpression())
1212
// CHECK-LABEL: ret void
1313
}
1414

1515
public func f2<U..., V...>(us: repeat each U, vs: repeat each V) {
16-
// CHECK: define {{.*}} @"$s1a2f22us2vsyxxQp_q_q_Qptr0_lF"(%swift.opaque** {{.*}}, %swift.opaque** {{.*}}, i{{32|64}} [[COUNT2_1:.*]], i{{32|64}} [[COUNT2_2:.*]], %swift.type** {{.*}}, %swift.type** {{.*}})
16+
// CHECK: define {{.*}} @"$s1a2f22us2vsyxxQp_q_q_QptRvzRv_r0_lF"(%swift.opaque** {{.*}}, %swift.opaque** {{.*}}, i{{32|64}} [[COUNT2_1:.*]], i{{32|64}} [[COUNT2_2:.*]], %swift.type** {{.*}}, %swift.type** {{.*}})
1717
// CHECK-DAG: store i{{32|64}} [[COUNT2_1]], i{{32|64}}* %[[COUNT2_1_A:.*]], align
1818
// CHECK-DAG: store i{{32|64}} [[COUNT2_2]], i{{32|64}}* %[[COUNT2_2_A:.*]], align
1919
// CHECK-DAG: call void @llvm.dbg.declare({{.*}}[[COUNT2_1_A]], metadata ![[COUNT2_1_VAR:[0-9]+]], metadata !DIExpression())
@@ -22,14 +22,14 @@ public func f2<U..., V...>(us: repeat each U, vs: repeat each V) {
2222
}
2323

2424
public func f3<T...>(ts: repeat each T, more_ts: repeat each T) {
25-
// CHECK: define {{.*}} @"$s1a2f32ts05more_B0yxxQp_xxQptlF"(%swift.opaque** {{.*}}, %swift.opaque** {{.*}}, i{{32|64}} [[COUNT3_1:.*]], %swift.type** {{.*}})
25+
// CHECK: define {{.*}} @"$s1a2f32ts05more_B0yxxQp_xxQptRvzlF"(%swift.opaque** {{.*}}, %swift.opaque** {{.*}}, i{{32|64}} [[COUNT3_1:.*]], %swift.type** {{.*}})
2626
// CHECK-DAG: store i{{32|64}} [[COUNT3_1]], i{{32|64}}* %[[COUNT3_1_A:.*]], align
2727
// CHECK-DAG: call void @llvm.dbg.declare({{.*}}[[COUNT3_1_A]], metadata ![[COUNT3_1_VAR:[0-9]+]], metadata !DIExpression())
2828
// CHECK-LABEL: ret void
2929
}
3030

3131
public func f4<U..., V...>(us: repeat (each U, each V)) {
32-
// CHECK: define {{.*}} @"$s1a2f42usyx_q_txQp_tq_Rhzr0_lF"(%swift.opaque** {{.*}}, i{{32|64}} [[COUNT4_1:.*]], %swift.type** {{.*}}, %swift.type** {{.*}})
32+
// CHECK: define {{.*}} @"$s1a2f42usyx_q_txQp_tq_RhzRvzRv_r0_lF"(%swift.opaque** {{.*}}, i{{32|64}} [[COUNT4_1:.*]], %swift.type** {{.*}}, %swift.type** {{.*}})
3333
// CHECK-DAG: store i{{32|64}} [[COUNT4_1]], i{{32|64}}* %[[COUNT4_1_A:.*]], align
3434
// CHECK-DAG: call void @llvm.dbg.declare({{.*}}[[COUNT4_1_A]], metadata ![[COUNT4_1_VAR:[0-9]+]], metadata !DIExpression())
3535
// CHECK-LABEL: ret void

test/DebugInfo/variadic-generics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// REQUIRES: asserts
77

88
public func foo<T...>(args: repeat each T) {
9-
// CHECK: define {{.*}} @"$s1a3foo4argsyxxQp_tlF"
9+
// CHECK: define {{.*}} @"$s1a3foo4argsyxxQp_tRvzlF"
1010
// CHECK-SAME: %swift.type** %[[TYPE_PACK_ARG:.*]])
1111
// CHECK: %[[TYPE_PACK_ALLOCA:.*]] = alloca %swift.type**
1212
// CHECK: call void @llvm.dbg.declare(metadata %swift.type*** %[[TYPE_PACK_ALLOCA]], metadata ![[TYPE_PACK_VAR:[0-9]+]], metadata !DIExpression())

test/IRGen/variadic_generic_functions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
// REQUIRES: PTRSIZE=64
77

8-
// CHECK-LABEL: define hidden swiftcc void @"$s26variadic_generic_functions2f11tyxxQp_tlF"(%swift.opaque** noalias nocapture %0, i64 %1, %swift.type** %T)
8+
// CHECK-LABEL: define hidden swiftcc void @"$s26variadic_generic_functions2f11tyxxQp_tRvzlF"(%swift.opaque** noalias nocapture %0, i64 %1, %swift.type** %T)
99
func f1<T...>(t: repeat each T) {}
1010

11-
// CHECK-LABEL: define hidden swiftcc void @"$s26variadic_generic_functions2f21t1uyxxQp_q_q_Qptr0_lF"(%swift.opaque** noalias nocapture %0, %swift.opaque** noalias nocapture %1, i64 %2, i64 %3, %swift.type** %T, %swift.type** %U)
11+
// CHECK-LABEL: define hidden swiftcc void @"$s26variadic_generic_functions2f21t1uyxxQp_q_q_QptRvzRv_r0_lF"(%swift.opaque** noalias nocapture %0, %swift.opaque** noalias nocapture %1, i64 %2, i64 %3, %swift.type** %T, %swift.type** %U)
1212
func f2<T..., U...>(t: repeat each T, u: repeat each U) {}
1313

14-
// CHECK-LABEL: define hidden swiftcc void @"$s26variadic_generic_functions2f31t1uyxxQp_q_xQptq_Rhzr0_lF"(%swift.opaque** noalias nocapture %0, %swift.opaque** noalias nocapture %1, i64 %2, %swift.type** %T, %swift.type** %U)
14+
// CHECK-LABEL: define hidden swiftcc void @"$s26variadic_generic_functions2f31t1uyxxQp_q_xQptq_RhzRvzRv_r0_lF"(%swift.opaque** noalias nocapture %0, %swift.opaque** noalias nocapture %1, i64 %2, %swift.type** %T, %swift.type** %U)
1515
func f3<T..., U...>(t: repeat each T, u: repeat each U) where (repeat (each T, each U)): Any {}
1616

1717
protocol P {}

test/Interpreter/variadic_generic_types.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@ struct G<T...> {
1111
}
1212
}
1313

14+
// CHECK: ()
15+
G< >().makeTuple()
16+
1417
// CHECK: (Array<Int>, Array<String>, Array<Float>)
1518
G<Int, String, Float>().makeTuple()

0 commit comments

Comments
 (0)