Skip to content

Commit e4fbde8

Browse files
Merge pull request #68996 from aschwaighofer/objective_c_protocol_symbolic_ref
Add support for objective c protocol symbolic references
2 parents 06b658c + 894095a commit e4fbde8

23 files changed

+251
-13
lines changed

docs/ABI/Mangling.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ The following symbolic reference kinds are currently implemented:
108108
symbolic-extended-existential-type-shape ::= '\x0B' .{4} // Reference points directly to a NonUniqueExtendedExistentialTypeShape
109109
#endif
110110

111+
#if SWIFT_RUNTIME_VERSION >= 5.TBD
112+
objective-c-protocol-relative-reference ::= `\x0C` .{4} // Reference points directly to a objective-c protcol reference
113+
#endif
114+
111115
A mangled name may also include ``\xFF`` bytes, which are only used for
112116
alignment padding. They do not affect what the mangled name references and can
113117
be skipped over and ignored.

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,10 @@ class ASTContext final {
944944
/// that fixes up the value witness table of @_rawLayout dependent types.
945945
AvailabilityContext getInitRawStructMetadataAvailability();
946946

947+
/// Get the runtime availability of being able to use symbolic references to
948+
/// objective c protocols.
949+
AvailabilityContext getObjCSymbolicReferencesAvailability();
950+
947951
/// Get the runtime availability of features introduced in the Swift 5.2
948952
/// compiler for the target platform.
949953
AvailabilityContext getSwift52Availability();

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,8 @@ class IRGenOptions {
408408
/// Enable runtime instantiation of value witness strings for generic types
409409
unsigned EnableLayoutStringValueWitnessesInstantiation : 1;
410410

411+
unsigned EnableObjectiveCProtocolSymbolicReferences : 1;
412+
411413
/// Instrument code to generate profiling information.
412414
unsigned GenerateProfile : 1;
413415

@@ -527,6 +529,7 @@ class IRGenOptions {
527529
UseTypeLayoutValueHandling(true), ForceStructTypeLayouts(false),
528530
EnableLayoutStringValueWitnesses(false),
529531
EnableLayoutStringValueWitnessesInstantiation(false),
532+
EnableObjectiveCProtocolSymbolicReferences(false),
530533
GenerateProfile(false), EnableDynamicReplacementChaining(false),
531534
DisableDebuggerShadowCopies(false),
532535
DisableConcreteTypeMetadataMangledNameAccessors(false),

include/swift/Demangling/DemangleNodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,5 +371,8 @@ NODE(OpaqueReturnTypeParent)
371371
// Added in Swift 5.9 + 1
372372
NODE(AsyncRemoved)
373373

374+
// Added in Swift 5.TBD
375+
NODE(ObjectiveCProtocolSymbolicReference)
376+
374377
#undef CONTEXT_NODE
375378
#undef NODE

include/swift/Demangling/Demangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ enum class SymbolicReferenceKind : uint8_t {
383383
UniqueExtendedExistentialTypeShape,
384384
/// A symbolic reference to a non-unique extended existential type shape.
385385
NonUniqueExtendedExistentialTypeShape,
386+
/// A symbolic reference to a objective C protocol ref.
387+
ObjectiveCProtocol,
386388
};
387389

388390
using SymbolicReferenceResolver_t = NodePointer (SymbolicReferenceKind,

include/swift/Demangling/TypeDecoder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ class TypeDecoder {
754754
case NodeKind::ConstrainedExistentialSelf:
755755
return Builder.createGenericTypeParameterType(/*depth*/ 0, /*index*/ 0);
756756

757+
case NodeKind::ObjectiveCProtocolSymbolicReference:
757758
case NodeKind::Protocol:
758759
case NodeKind::ProtocolSymbolicReference: {
759760
if (auto Proto = decodeMangledProtocolType(Node, depth + 1)) {
@@ -1574,8 +1575,9 @@ class TypeDecoder {
15741575
if (node->getKind() == NodeKind::Type)
15751576
return decodeMangledProtocolType(node->getChild(0), depth + 1);
15761577

1577-
if ((node->getNumChildren() < 2 || node->getKind() != NodeKind::Protocol)
1578-
&& node->getKind() != NodeKind::ProtocolSymbolicReference)
1578+
if ((node->getNumChildren() < 2 || node->getKind() != NodeKind::Protocol) &&
1579+
node->getKind() != NodeKind::ProtocolSymbolicReference &&
1580+
node->getKind() != NodeKind::ObjectiveCProtocolSymbolicReference)
15791581
return BuiltProtocolDecl();
15801582

15811583
#if SWIFT_OBJC_INTEROP

include/swift/Option/FrontendOptions.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,13 @@ def disable_new_llvm_pass_manager :
12421242
Flag<["-"], "disable-new-llvm-pass-manager">,
12431243
HelpText<"Disable the new llvm pass manager">;
12441244

1245+
def enable_objective_c_protocol_symbolic_references :
1246+
Flag<["-"], "enable-objective-c-protocol-symbolic-references">,
1247+
HelpText<"Enable objective-c protocol symbolic references">;
1248+
def disable_objective_c_protocol_symbolic_references :
1249+
Flag<["-"], "disable-objective-c-protocol-symbolic-references">,
1250+
HelpText<"Disable objective-c protocol symbolic references">;
1251+
12451252
def disable_emit_generic_class_ro_t_list :
12461253
Flag<["-"], "disable-emit-generic-class-ro_t-list">,
12471254
HelpText<"Disable emission of a section with references to class_ro_t of "

include/swift/Remote/MetadataReader.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,33 @@ class MetadataReader {
512512
Node::Kind::NonUniqueExtendedExistentialTypeShapeSymbolicReference,
513513
resolved.getResolvedAddress().getAddressData());
514514
}
515+
case Demangle::SymbolicReferenceKind::ObjectiveCProtocol: {
516+
// 'resolved' points to a struct of two relative addresses.
517+
// The second entry is a relative address to the mangled protocol
518+
// without symbolic references.
519+
auto addr =
520+
resolved.getResolvedAddress().getAddressData() + sizeof(int32_t);
521+
int32_t offset;
522+
Reader->readInteger(RemoteAddress(addr), &offset);
523+
auto addrOfTypeRef = addr + offset;
524+
resolved = Reader->getSymbol(RemoteAddress(addrOfTypeRef));
525+
526+
// Dig out the protocol from the protocol list.
527+
auto protocolList = readMangledName(resolved.getResolvedAddress(),
528+
MangledNameKind::Type, dem);
529+
assert(protocolList->getFirstChild()
530+
->getFirstChild()
531+
->getFirstChild()
532+
->getFirstChild()
533+
->getKind() == Node::Kind::Protocol);
534+
auto protocol = protocolList->getFirstChild()
535+
->getFirstChild()
536+
->getFirstChild()
537+
->getFirstChild();
538+
auto protocolType = dem.createNode(Node::Kind::Type);
539+
protocolType->addChild(protocol, dem);
540+
return protocolType;
541+
}
515542
}
516543

517544
return nullptr;

lib/AST/Availability.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,10 @@ ASTContext::getInitRawStructMetadataAvailability() {
585585
return getSwiftFutureAvailability();
586586
}
587587

588+
AvailabilityContext ASTContext::getObjCSymbolicReferencesAvailability() {
589+
return getSwiftFutureAvailability();
590+
}
591+
588592
AvailabilityContext ASTContext::getSwift52Availability() {
589593
auto target = LangOpts.Target;
590594

lib/Demangling/Demangler.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static bool isDeclName(Node::Kind kind) {
4545
case Node::Kind::InfixOperator:
4646
case Node::Kind::TypeSymbolicReference:
4747
case Node::Kind::ProtocolSymbolicReference:
48+
case Node::Kind::ObjectiveCProtocolSymbolicReference:
4849
return true;
4950
default:
5051
return false;
@@ -58,6 +59,7 @@ static bool isAnyGeneric(Node::Kind kind) {
5859
case Node::Kind::Enum:
5960
case Node::Kind::Protocol:
6061
case Node::Kind::ProtocolSymbolicReference:
62+
case Node::Kind::ObjectiveCProtocolSymbolicReference:
6163
case Node::Kind::OtherNominalType:
6264
case Node::Kind::TypeAlias:
6365
case Node::Kind::TypeSymbolicReference:
@@ -278,6 +280,7 @@ static bool isProtocolNode(Demangle::NodePointer Node) {
278280
return isProtocolNode(Node->getChild(0));
279281
case Demangle::Node::Kind::Protocol:
280282
case Demangle::Node::Kind::ProtocolSymbolicReference:
283+
case Demangle::Node::Kind::ObjectiveCProtocolSymbolicReference:
281284
return true;
282285
default:
283286
return false;
@@ -870,6 +873,10 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind) {
870873
kind = SymbolicReferenceKind::NonUniqueExtendedExistentialTypeShape;
871874
direct = Directness::Direct;
872875
break;
876+
case 0x0c:
877+
kind = SymbolicReferenceKind::ObjectiveCProtocol;
878+
direct = Directness::Direct;
879+
break;
873880
// These are all currently reserved but unused.
874881
case 0x03: // direct to protocol conformance descriptor
875882
case 0x04: // indirect to protocol conformance descriptor
@@ -893,8 +900,10 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind) {
893900

894901
// Types register as substitutions even when symbolically referenced.
895902
// OOPS: Except for opaque type references!
896-
if (kind == SymbolicReferenceKind::Context &&
897-
resolved->getKind() != Node::Kind::OpaqueTypeDescriptorSymbolicReference &&
903+
if ((kind == SymbolicReferenceKind::Context ||
904+
kind == SymbolicReferenceKind::ObjectiveCProtocol) &&
905+
resolved->getKind() !=
906+
Node::Kind::OpaqueTypeDescriptorSymbolicReference &&
898907
resolved->getKind() != Node::Kind::OpaqueReturnTypeOf)
899908
addSubstitution(resolved);
900909
return resolved;
@@ -1753,6 +1762,9 @@ NodePointer Demangler::popProtocol() {
17531762

17541763
if (NodePointer SymbolicRef = popNode(Node::Kind::ProtocolSymbolicReference)){
17551764
return SymbolicRef;
1765+
} else if (NodePointer SymbolicRef =
1766+
popNode(Node::Kind::ObjectiveCProtocolSymbolicReference)) {
1767+
return SymbolicRef;
17561768
}
17571769

17581770
NodePointer Name = popNode(isDeclName);
@@ -2584,6 +2596,8 @@ NodePointer Demangler::popAssocTypeName() {
25842596
// If we haven't seen a protocol, check for a symbolic reference.
25852597
if (!Proto)
25862598
Proto = popNode(Node::Kind::ProtocolSymbolicReference);
2599+
if (!Proto)
2600+
Proto = popNode(Node::Kind::ObjectiveCProtocolSymbolicReference);
25872601

25882602
NodePointer Id = popNode(Node::Kind::Identifier);
25892603
NodePointer AssocTy = createWithChild(Node::Kind::DependentAssociatedTypeRef, Id);

0 commit comments

Comments
 (0)