Skip to content

Commit 4207738

Browse files
committed
Add mangling and IRGen LinkEntity for Objective-C resilient class stubs
1 parent 583c0d9 commit 4207738

File tree

13 files changed

+146
-15
lines changed

13 files changed

+146
-15
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ Globals
112112
global ::= nominal-type 'Mn' // nominal type descriptor
113113
global ::= nominal-type 'Mu' // class method lookup function
114114
global ::= nominal-type 'MU' // ObjC metadata update callback function
115+
global ::= nominal-type 'Ms' // ObjC resilient class stub
116+
global ::= nominal-type 'Mt' // Full ObjC resilient class stub (private)
115117
global ::= module 'MXM' // module descriptor
116118
global ::= context 'MXE' // extension descriptor
117119
global ::= context 'MXX' // anonymous context descriptor

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ NODE(MetatypeRepresentation)
134134
NODE(Metaclass)
135135
NODE(MethodLookupFunction)
136136
NODE(ObjCMetadataUpdateFunction)
137+
NODE(ObjCResilientClassStub)
138+
NODE(FullObjCResilientClassStub)
137139
CONTEXT_NODE(ModifyAccessor)
138140
CONTEXT_NODE(Module)
139141
CONTEXT_NODE(NativeOwningAddressor)

include/swift/IRGen/Linking.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class LinkEntity {
9696
// This field appears in the ValueWitness kind.
9797
ValueWitnessShift = 8, ValueWitnessMask = 0xFF00,
9898

99-
// This field appears in the TypeMetadata kind.
99+
// This field appears in the TypeMetadata and ObjCResilientClassStub kinds.
100100
MetadataAddressShift = 8, MetadataAddressMask = 0x0300,
101101

102102
// This field appears in associated type access functions.
@@ -164,6 +164,12 @@ class LinkEntity {
164164
/// ClassMetadataStrategy::Update or ::FixedOrUpdate.
165165
ObjCMetadataUpdateFunction,
166166

167+
/// A stub that we emit to allow Clang-generated code to statically refer
168+
/// to Swift classes with resiliently-sized metadata, since the metadata
169+
/// is not statically-emitted. Used when getClassMetadataStrategy() is
170+
/// equal to ClassMetadataStrategy::Resilient.
171+
ObjCResilientClassStub,
172+
167173
/// A class metadata base offset global variable. This stores the offset
168174
/// of the immediate members of a class (generic parameters, field offsets,
169175
/// vtable offsets) in the class's metadata. The immediate members begin
@@ -613,13 +619,19 @@ class LinkEntity {
613619
return entity;
614620
}
615621

622+
static LinkEntity forObjCResilientClassStub(ClassDecl *decl,
623+
TypeMetadataAddress addr) {
624+
LinkEntity entity;
625+
entity.setForDecl(Kind::ObjCResilientClassStub, decl);
626+
entity.Data |= LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
627+
return entity;
628+
}
629+
616630
static LinkEntity forTypeMetadata(CanType concreteType,
617631
TypeMetadataAddress addr) {
618632
LinkEntity entity;
619-
entity.Pointer = concreteType.getPointer();
620-
entity.SecondaryPointer = nullptr;
621-
entity.Data = LINKENTITY_SET_FIELD(Kind, unsigned(Kind::TypeMetadata))
622-
| LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
633+
entity.setForType(Kind::TypeMetadata, concreteType);
634+
entity.Data |= LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
623635
return entity;
624636
}
625637

@@ -1021,7 +1033,8 @@ class LinkEntity {
10211033
return ValueWitness(LINKENTITY_GET_FIELD(Data, ValueWitness));
10221034
}
10231035
TypeMetadataAddress getMetadataAddress() const {
1024-
assert(getKind() == Kind::TypeMetadata);
1036+
assert(getKind() == Kind::TypeMetadata ||
1037+
getKind() == Kind::ObjCResilientClassStub);
10251038
return (TypeMetadataAddress)LINKENTITY_GET_FIELD(Data, MetadataAddress);
10261039
}
10271040
bool isForeignTypeMetadataCandidate() const {

lib/Demangling/Demangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,10 @@ NodePointer Demangler::demangleMetatype() {
18091809
return createWithPoppedType(Node::Kind::MethodLookupFunction);
18101810
case 'U':
18111811
return createWithPoppedType(Node::Kind::ObjCMetadataUpdateFunction);
1812+
case 's':
1813+
return createWithPoppedType(Node::Kind::ObjCResilientClassStub);
1814+
case 't':
1815+
return createWithPoppedType(Node::Kind::FullObjCResilientClassStub);
18121816
case 'B':
18131817
return createWithChild(Node::Kind::ReflectionMetadataBuiltinDescriptor,
18141818
popNode(Node::Kind::Type));

lib/Demangling/NodePrinter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ class NodePrinter {
353353
case Node::Kind::Extension:
354354
case Node::Kind::EnumCase:
355355
case Node::Kind::FieldOffset:
356+
case Node::Kind::FullObjCResilientClassStub:
356357
case Node::Kind::FullTypeMetadata:
357358
case Node::Kind::Function:
358359
case Node::Kind::FunctionSignatureSpecialization:
@@ -411,6 +412,7 @@ class NodePrinter {
411412
case Node::Kind::ObjCAttribute:
412413
case Node::Kind::ObjCBlock:
413414
case Node::Kind::ObjCMetadataUpdateFunction:
415+
case Node::Kind::ObjCResilientClassStub:
414416
case Node::Kind::Owned:
415417
case Node::Kind::OwningAddressor:
416418
case Node::Kind::OwningMutableAddressor:
@@ -981,6 +983,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
981983
Printer << "ObjC metadata update function for ";
982984
print(Node->getChild(0));
983985
return nullptr;
986+
case Node::Kind::ObjCResilientClassStub:
987+
Printer << "ObjC resilient class stub for ";
988+
print(Node->getChild(0));
989+
return nullptr;
990+
case Node::Kind::FullObjCResilientClassStub:
991+
Printer << "full ObjC resilient class stub for ";
992+
print(Node->getChild(0));
993+
return nullptr;
984994
case Node::Kind::OutlinedBridgedMethod:
985995
Printer << "outlined bridged method (" << Node->getText() << ") of ";
986996
return nullptr;

lib/Demangling/OldRemangler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,14 @@ void Remangler::mangleObjCMetadataUpdateFunction(Node *node) {
18071807
Buffer << "<objc-metadata-update-function>";
18081808
}
18091809

1810+
void Remangler::mangleObjCResilientClassStub(Node *node) {
1811+
Buffer << "<objc-resilient-class-stub>";
1812+
}
1813+
1814+
void Remangler::mangleFullObjCResilientClassStub(Node *node) {
1815+
Buffer << "<full-objc-resilient-class-stub>";
1816+
}
1817+
18101818
void Remangler::mangleEmptyList(Node *node) {
18111819
Buffer << "<empty>";
18121820
}

lib/Demangling/Remangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,6 +2135,16 @@ void Remangler::mangleObjCMetadataUpdateFunction(Node *node) {
21352135
Buffer << "MU";
21362136
}
21372137

2138+
void Remangler::mangleObjCResilientClassStub(Node *node) {
2139+
mangleSingleChildNode(node);
2140+
Buffer << "Ms";
2141+
}
2142+
2143+
void Remangler::mangleFullObjCResilientClassStub(Node *node) {
2144+
mangleSingleChildNode(node);
2145+
Buffer << "Mt";
2146+
}
2147+
21382148
void Remangler::mangleThrowsAnnotation(Node *node) {
21392149
Buffer << 'K';
21402150
}

lib/IRGen/GenClass.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,9 +2021,9 @@ namespace {
20212021
} // end anonymous namespace
20222022

20232023
static llvm::Function *emitObjCMetadataUpdateFunction(IRGenModule &IGM,
2024-
ClassDecl *cls) {
2024+
ClassDecl *D) {
20252025
llvm::Function *f =
2026-
IGM.getAddrOfObjCMetadataUpdateFunction(cls, ForDefinition);
2026+
IGM.getAddrOfObjCMetadataUpdateFunction(D, ForDefinition);
20272027
f->setAttributes(IGM.constructInitialAttributes());
20282028

20292029
IRGenFunction IGF(IGM, f);
@@ -2037,7 +2037,7 @@ static llvm::Function *emitObjCMetadataUpdateFunction(IRGenModule &IGM,
20372037

20382038
// Just directly call our metadata accessor. This should actually
20392039
// return the same metadata; the Objective-C runtime enforces this.
2040-
auto type = cls->getDeclaredType()->getCanonicalType();
2040+
auto type = D->getDeclaredType()->getCanonicalType();
20412041
auto *metadata = IGF.emitTypeMetadataRef(type,
20422042
MetadataState::Complete)
20432043
.getMetadata();

lib/IRGen/GenDecl.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,7 +2960,7 @@ IRGenModule::getAddrOfMetaclassObject(ClassDecl *decl,
29602960
llvm::Function *
29612961
IRGenModule::getAddrOfObjCMetadataUpdateFunction(ClassDecl *classDecl,
29622962
ForDefinition_t forDefinition) {
2963-
IRGen.noteUseOfTypeMetadata(classDecl);
2963+
assert(ObjCInterop);
29642964

29652965
LinkEntity entity = LinkEntity::forObjCMetadataUpdateFunction(classDecl);
29662966
llvm::Function *&entry = GlobalFuncs[entity];
@@ -2970,14 +2970,25 @@ IRGenModule::getAddrOfObjCMetadataUpdateFunction(ClassDecl *classDecl,
29702970
}
29712971

29722972
// Class _Nullable callback(Class _Nonnull cls, void * _Nullable arg);
2973-
llvm::Type *params[] = { ObjCClassPtrTy, Int8PtrTy };
2974-
auto fnType = llvm::FunctionType::get(ObjCClassPtrTy, params, false);
2975-
Signature signature(fnType, llvm::AttributeList(), DefaultCC);
2973+
Signature signature(ObjCUpdateCallbackTy, llvm::AttributeList(), DefaultCC);
29762974
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
29772975
entry = createFunction(*this, link, signature);
29782976
return entry;
29792977
}
29802978

2979+
/// Fetch the declaration of an Objective-C resilient class stub.
2980+
llvm::Constant *
2981+
IRGenModule::getAddrOfObjCResilientClassStub(ClassDecl *classDecl,
2982+
ForDefinition_t forDefinition,
2983+
TypeMetadataAddress addr) {
2984+
assert(ObjCInterop);
2985+
assert(getClassMetadataStrategy(classDecl) ==
2986+
ClassMetadataStrategy::Resilient);
2987+
2988+
LinkEntity entity = LinkEntity::forObjCResilientClassStub(classDecl, addr);
2989+
return getAddrOfLLVMVariable(entity, forDefinition, DebugTypeInfo());
2990+
}
2991+
29812992
/// Fetch the type metadata access function for a non-generic type.
29822993
llvm::Function *
29832994
IRGenModule::getAddrOfTypeMetadataAccessFunction(CanType type,

lib/IRGen/IRGenMangler.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ class IRGenMangler : public Mangle::ASTMangler {
107107
return mangleNominalTypeSymbol(Decl, "MU");
108108
}
109109

110+
std::string mangleObjCResilientClassStub(const ClassDecl *Decl) {
111+
return mangleNominalTypeSymbol(Decl, "Ms");
112+
}
113+
114+
std::string mangleFullObjCResilientClassStub(const ClassDecl *Decl) {
115+
return mangleNominalTypeSymbol(Decl, "Mt");
116+
}
117+
110118
std::string mangleClassMetadataBaseOffset(const ClassDecl *Decl) {
111119
return mangleNominalTypeSymbol(Decl, "Mo");
112120
}

0 commit comments

Comments
 (0)