Skip to content

Introduce a mangling for multiple opaque types within the declaration. #40766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -737,15 +737,17 @@ implementation details of a function type.
::

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

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

#if SWIFT_VERSION >= 5.4
type ::= 'Qu' // opaque result type (of current decl)
type ::= 'Qu' // opaque result type (of current decl, first param)
// used for ObjC class runtime name purposes.
type ::= 'QU' INDEX
#endif

Opaque return types have a special short representation in the mangling of
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -329,5 +329,8 @@ NODE(AsyncSuspendResumePartialFunction)
// Added in Swift 5.6
NODE(AccessibleFunctionRecord)

// Added in Swift 5.7
NODE(OpaqueReturnTypeIndexed)

#undef CONTEXT_NODE
#undef NODE
8 changes: 6 additions & 2 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,10 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
auto opaqueDecl = opaqueType->getDecl();
if (opaqueDecl->getNamingDecl() == forDecl) {
assert(opaqueType->getSubstitutions().isIdentity());
return appendOperator("Qr");
if (opaqueType->getOrdinal() == 0)
return appendOperator("Qr");

return appendOperator("QR", Index(opaqueType->getOrdinal() - 1));
}

// Otherwise, try to substitute it.
Expand Down Expand Up @@ -1358,7 +1361,8 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
addTypeSubstitution(nestedType, sig);
return;
}


// FIXME: Never actually used.
appendType(nestedType->getParent(), sig, forDecl);
appendIdentifier(nestedType->getName().str());
appendOperator("Qa");
Expand Down
6 changes: 6 additions & 0 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,12 @@ NodePointer Demangler::demangleArchetype() {
case 'r': {
return createType(createNode(Node::Kind::OpaqueReturnType));
}
case 'R': {
int ordinal = demangleIndex();
if (ordinal < 0)
return NULL;
return createType(createNode(Node::Kind::OpaqueReturnTypeIndexed, ordinal));
}

case 'x': {
NodePointer T = demangleAssociatedTypeSimple(nullptr);
Expand Down
2 changes: 2 additions & 0 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ class NodePrinter {
case Node::Kind::OpaqueType:
case Node::Kind::OpaqueTypeDescriptorSymbolicReference:
case Node::Kind::OpaqueReturnType:
case Node::Kind::OpaqueReturnTypeIndexed:
case Node::Kind::OpaqueReturnTypeOf:
case Node::Kind::CanonicalSpecializedGenericMetaclass:
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
Expand Down Expand Up @@ -2817,6 +2818,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
Printer << ")";
return nullptr;
case Node::Kind::OpaqueReturnType:
case Node::Kind::OpaqueReturnTypeIndexed:
Printer << "some";
return nullptr;
case Node::Kind::OpaqueReturnTypeOf:
Expand Down
7 changes: 7 additions & 0 deletions lib/Demangling/OldDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,13 @@ class OldDemangler {
// Special mangling for opaque return type.
return Factory.createNode(Node::Kind::OpaqueReturnType);
}
if (Mangled.nextIf('U')) {
// Special mangling for opaque return type.
Node::IndexType ordinal;
if (!demangleIndex(ordinal, depth))
return nullptr;
return Factory.createNode(Node::Kind::OpaqueReturnTypeIndexed, ordinal);
}
return demangleArchetypeType(depth + 1);
}
if (c == 'q') {
Expand Down
5 changes: 5 additions & 0 deletions lib/Demangling/OldRemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2643,6 +2643,11 @@ ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
Buffer << "Qu";
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeIndexed(Node *node, unsigned depth) {
Buffer << "QU";
mangleIndex(node->getIndex());
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node,
EntityContext &ctx,
unsigned depth) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3280,6 +3280,11 @@ ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
Buffer << "Qr";
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeIndexed(Node *node, unsigned depth) {
Buffer << "QR";
mangleIndex(node->getIndex());
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1));
Buffer << "QO";
Expand Down
4 changes: 2 additions & 2 deletions test/IRGen/opaque_result_type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public func useFoo(x: String, y: C) {
let _ = bauble(z: y, u: y)
}

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

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

// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type9gimmeBoomypyF
// CHECK: call swiftcc void @"$s18opaque_result_type4BoomV5prop15prop2ACyxGSi_AcEQr_QrtvpQOyx_Qo__AcEQr_QrtvpQOyx_Qo0_ttcfcfA0_"
// CHECK: call swiftcc void @"$s18opaque_result_type4BoomV5prop15prop2ACyxGSi_AcEQr_QR_tvpQOyx_Qo__AcEQr_QR_tvpQOyx_Qo0_ttcfcfA0_"
public func gimmeBoom() -> Any {
Boom<String>(prop1: 5)
}
Expand Down
4 changes: 2 additions & 2 deletions test/IRGen/opaque_result_type_debug.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ public func bar<T: P>(genericValue: T) {
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueValue",{{.*}} type: ![[LET_OPAQUE_TYPE]])
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaquePropValue",{{.*}} type: ![[LET_OPAQUE_PROP_TYPE]])
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueSubValue",{{.*}} type: ![[LET_OPAQUE_SUB_TYPE]])
// CHECK-DAG: ![[OPAQUE_ARRAY_FIRST_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QrSgtGyFQOyQo_D"
// CHECK-DAG: ![[OPAQUE_ARRAY_FIRST_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QR_SgtGyFQOyQo_D"
// CHECK-DAG: ![[LET_OPAQUE_ARRAY_FIRST_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[OPAQUE_ARRAY_FIRST_TYPE]])
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueArrayFirst",{{.*}} type: ![[LET_OPAQUE_ARRAY_FIRST_TYPE]])
// CHECK-DAG: ![[OPAQUE_ARRAY_SECOND_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QrSgtGyFQOyQo0_D"
// CHECK-DAG: ![[OPAQUE_ARRAY_SECOND_TYPE:[0-9]+]] = !DICompositeType({{.*}} name: "$s30opaque_result_type_debug_other3barSayQr_QR_SgtGyFQOyQo0_D"
// CHECK-DAG: ![[LET_OPAQUE_ARRAY_SECOND_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[OPAQUE_ARRAY_SECOND_TYPE]])
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueArraySecond",{{.*}} type: ![[LET_OPAQUE_ARRAY_SECOND_TYPE]])
2 changes: 1 addition & 1 deletion test/Serialization/opaque_type_structured.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func acceptR<T: R>(_: T) { }
// AST: func f() -> (some P, [some Q])

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