Skip to content

Commit f89ff04

Browse files
committed
Introduce a mangling for multiple opaque types within the declaration.
The `Qr` mangling is used to refer to the opaque type within the declaration that produces the opaque type. When there are multiple opaque types, e.g., due to structural or named opaque result types, it does not specify which of the opaque type parameters it refers to. Introduce a new mangling `QR INDEX` for opaque type parameters after the first, retaining the `Qr` mangling for the first opaque type parameter. This way, existing (non-structural) uses of opaque result types retain the same manglings, but uses of structural or named opaque result types (new features) will have distinct manglings. Note that this mangling within a declaration is only used for the declaration itself, and not for references to the opaque type of the declaration, so there is no impact on the runtime demangler.
1 parent bd0fa0b commit f89ff04

File tree

11 files changed

+43
-9
lines changed

11 files changed

+43
-9
lines changed

docs/ABI/Mangling.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,15 +737,17 @@ implementation details of a function type.
737737
::
738738

739739
#if SWIFT_VERSION >= 5.1
740-
type ::= 'Qr' // opaque result type (of current decl)
740+
type ::= 'Qr' // opaque result type (of current decl, used for the first opaque type parameter only)
741+
type ::= 'QR' INDEX // same as above, for subsequent opaque type parameters, INDEX is the ordinal -1
741742
type ::= opaque-type-decl-name bound-generic-args 'Qo' INDEX // opaque type
742743

743744
opaque-type-decl-name ::= entity 'QO' // opaque result type of specified decl
744745
#endif
745746

746747
#if SWIFT_VERSION >= 5.4
747-
type ::= 'Qu' // opaque result type (of current decl)
748+
type ::= 'Qu' // opaque result type (of current decl, first param)
748749
// used for ObjC class runtime name purposes.
750+
type ::= 'QU' INDEX
749751
#endif
750752

751753
Opaque return types have a special short representation in the mangling of

include/swift/Demangling/DemangleNodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,5 +329,8 @@ NODE(AsyncSuspendResumePartialFunction)
329329
// Added in Swift 5.6
330330
NODE(AccessibleFunctionRecord)
331331

332+
// Added in Swift 5.7
333+
NODE(OpaqueReturnTypeIndexed)
334+
332335
#undef CONTEXT_NODE
333336
#undef NODE

lib/AST/ASTMangler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,10 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
13181318
auto opaqueDecl = opaqueType->getDecl();
13191319
if (opaqueDecl->getNamingDecl() == forDecl) {
13201320
assert(opaqueType->getSubstitutions().isIdentity());
1321-
return appendOperator("Qr");
1321+
if (opaqueType->getOrdinal() == 0)
1322+
return appendOperator("Qr");
1323+
1324+
return appendOperator("QR", Index(opaqueType->getOrdinal() - 1));
13221325
}
13231326

13241327
// Otherwise, try to substitute it.
@@ -1358,7 +1361,8 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
13581361
addTypeSubstitution(nestedType, sig);
13591362
return;
13601363
}
1361-
1364+
1365+
// FIXME: Never actually used.
13621366
appendType(nestedType->getParent(), sig, forDecl);
13631367
appendIdentifier(nestedType->getName().str());
13641368
appendOperator("Qa");

lib/Demangling/Demangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,6 +2206,12 @@ NodePointer Demangler::demangleArchetype() {
22062206
case 'r': {
22072207
return createType(createNode(Node::Kind::OpaqueReturnType));
22082208
}
2209+
case 'R': {
2210+
int ordinal = demangleIndex();
2211+
if (ordinal < 0)
2212+
return NULL;
2213+
return createType(createNode(Node::Kind::OpaqueReturnTypeIndexed, ordinal));
2214+
}
22092215

22102216
case 'x': {
22112217
NodePointer T = demangleAssociatedTypeSimple(nullptr);

lib/Demangling/NodePrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ class NodePrinter {
568568
case Node::Kind::OpaqueType:
569569
case Node::Kind::OpaqueTypeDescriptorSymbolicReference:
570570
case Node::Kind::OpaqueReturnType:
571+
case Node::Kind::OpaqueReturnTypeIndexed:
571572
case Node::Kind::OpaqueReturnTypeOf:
572573
case Node::Kind::CanonicalSpecializedGenericMetaclass:
573574
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
@@ -2817,6 +2818,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
28172818
Printer << ")";
28182819
return nullptr;
28192820
case Node::Kind::OpaqueReturnType:
2821+
case Node::Kind::OpaqueReturnTypeIndexed:
28202822
Printer << "some";
28212823
return nullptr;
28222824
case Node::Kind::OpaqueReturnTypeOf:

lib/Demangling/OldDemangler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,13 @@ class OldDemangler {
20782078
// Special mangling for opaque return type.
20792079
return Factory.createNode(Node::Kind::OpaqueReturnType);
20802080
}
2081+
if (Mangled.nextIf('U')) {
2082+
// Special mangling for opaque return type.
2083+
Node::IndexType ordinal;
2084+
if (!demangleIndex(ordinal, depth))
2085+
return nullptr;
2086+
return Factory.createNode(Node::Kind::OpaqueReturnTypeIndexed, ordinal);
2087+
}
20812088
return demangleArchetypeType(depth + 1);
20822089
}
20832090
if (c == 'q') {

lib/Demangling/OldRemangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,6 +2643,11 @@ ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
26432643
Buffer << "Qu";
26442644
return ManglingError::Success;
26452645
}
2646+
ManglingError Remangler::mangleOpaqueReturnTypeIndexed(Node *node, unsigned depth) {
2647+
Buffer << "QU";
2648+
mangleIndex(node->getIndex());
2649+
return ManglingError::Success;
2650+
}
26462651
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node,
26472652
EntityContext &ctx,
26482653
unsigned depth) {

lib/Demangling/Remangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,6 +3280,11 @@ ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
32803280
Buffer << "Qr";
32813281
return ManglingError::Success;
32823282
}
3283+
ManglingError Remangler::mangleOpaqueReturnTypeIndexed(Node *node, unsigned depth) {
3284+
Buffer << "QR";
3285+
mangleIndex(node->getIndex());
3286+
return ManglingError::Success;
3287+
}
32833288
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node, unsigned depth) {
32843289
RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1));
32853290
Buffer << "QO";

test/IRGen/opaque_result_type.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public func useFoo(x: String, y: C) {
188188
let _ = bauble(z: y, u: y)
189189
}
190190

191-
// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type6bauble1z1uSayQr_QrSgtGx_q_tAA6MarkerRzAA1PRzAA1QRzAaIR_r0_lF"
191+
// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type6bauble1z1uSayQr_QR_SgtGx_q_tAA6MarkerRzAA1PRzAA1QRzAaIR_r0_lF"
192192

193193
// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type6useFoo1x1yySS_AA1CCtF"
194194
// CHECK: [[OPAQUE:%.*]] = call {{.*}} @"$s18opaque_result_type3baz1zQrx_tAA1PRzAA1QRzlFQOMg"
@@ -203,7 +203,7 @@ struct Boom<T: P> {
203203
}
204204

205205
// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type9gimmeBoomypyF
206-
// CHECK: call swiftcc void @"$s18opaque_result_type4BoomV5prop15prop2ACyxGSi_AcEQr_QrtvpQOyx_Qo__AcEQr_QrtvpQOyx_Qo0_ttcfcfA0_"
206+
// CHECK: call swiftcc void @"$s18opaque_result_type4BoomV5prop15prop2ACyxGSi_AcEQr_QR_tvpQOyx_Qo__AcEQr_QR_tvpQOyx_Qo0_ttcfcfA0_"
207207
public func gimmeBoom() -> Any {
208208
Boom<String>(prop1: 5)
209209
}

test/IRGen/opaque_result_type_debug.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ public func bar<T: P>(genericValue: T) {
6868
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueValue",{{.*}} type: ![[LET_OPAQUE_TYPE]])
6969
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaquePropValue",{{.*}} type: ![[LET_OPAQUE_PROP_TYPE]])
7070
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueSubValue",{{.*}} type: ![[LET_OPAQUE_SUB_TYPE]])
71-
// CHECK-DAG: ![[OPAQUE_ARRAY_FIRST_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QrSgtGyFQOyQo_D"
71+
// CHECK-DAG: ![[OPAQUE_ARRAY_FIRST_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QR_SgtGyFQOyQo_D"
7272
// CHECK-DAG: ![[LET_OPAQUE_ARRAY_FIRST_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[OPAQUE_ARRAY_FIRST_TYPE]])
7373
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueArrayFirst",{{.*}} type: ![[LET_OPAQUE_ARRAY_FIRST_TYPE]])
74-
// CHECK-DAG: ![[OPAQUE_ARRAY_SECOND_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QrSgtGyFQOyQo0_D"
74+
// CHECK-DAG: ![[OPAQUE_ARRAY_SECOND_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QR_SgtGyFQOyQo0_D"
7575
// CHECK-DAG: ![[LET_OPAQUE_ARRAY_SECOND_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[OPAQUE_ARRAY_SECOND_TYPE]])
7676
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueArraySecond",{{.*}} type: ![[LET_OPAQUE_ARRAY_SECOND_TYPE]])

test/Serialization/opaque_type_structured.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ func acceptR<T: R>(_: T) { }
99
// AST: func f() -> (some P, [some Q])
1010

1111
func passAnX(x: X) {
12-
// SIL: $@convention(method) (@in_guaranteed X) -> (@out @_opaqueReturnTypeOf("$s20OpaqueTypeStructured1XV1fQr_SayQrGtyF", 0) __, @owned Array<@_opaqueReturnTypeOf("$s20OpaqueTypeStructured1XV1fQr_SayQrGtyF", 1) __>)
12+
// SIL: $@convention(method) (@in_guaranteed X) -> (@out @_opaqueReturnTypeOf("$s20OpaqueTypeStructured1XV1fQr_SayQR_GtyF", 0) __, @owned Array<@_opaqueReturnTypeOf("$s20OpaqueTypeStructured1XV1fQr_SayQR_GtyF", 1) __>)
1313
acceptR(x)
1414
let _: X.A = x.f()
1515
}

0 commit comments

Comments
 (0)