Skip to content

Commit 4c475e6

Browse files
authored
Merge pull request #20235 from slavapestov/remove-imported-reflection-field-descriptors
Remove imported reflection field descriptors
2 parents 3288fe3 + 9074136 commit 4c475e6

File tree

16 files changed

+296
-147
lines changed

16 files changed

+296
-147
lines changed

include/swift/Demangling/TypeDecoder.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/Demangling/Demangler.h"
2323
#include "swift/Basic/LLVM.h"
2424
#include "swift/Runtime/Unreachable.h"
25+
#include "swift/Strings.h"
2526
#include <vector>
2627

2728
namespace swift {
@@ -75,6 +76,34 @@ class FunctionParam {
7576
}
7677
};
7778

79+
80+
#if SWIFT_OBJC_INTEROP
81+
/// For a mangled node that refers to an Objective-C class or protocol,
82+
/// return the class or protocol name.
83+
static inline Optional<StringRef> getObjCClassOrProtocolName(
84+
const Demangle::NodePointer &node) {
85+
if (node->getKind() != Demangle::Node::Kind::Class &&
86+
node->getKind() != Demangle::Node::Kind::Protocol)
87+
return None;
88+
89+
if (node->getNumChildren() != 2)
90+
return None;
91+
92+
// Check whether we have the __ObjC module.
93+
auto moduleNode = node->getChild(0);
94+
if (moduleNode->getKind() != Demangle::Node::Kind::Module ||
95+
moduleNode->getText() != MANGLING_MODULE_OBJC)
96+
return None;
97+
98+
// Check whether we have an identifier.
99+
auto nameNode = node->getChild(1);
100+
if (nameNode->getKind() != Demangle::Node::Kind::Identifier)
101+
return None;
102+
103+
return nameNode->getText();
104+
}
105+
#endif
106+
78107
/// Decode a mangled type to construct an abstract type, forming such
79108
/// types by invoking a custom builder.
80109
template <typename BuilderType>
@@ -112,6 +141,13 @@ class TypeDecoder {
112141

113142
return decodeMangledType(Node->getChild(0));
114143
case NodeKind::Class:
144+
{
145+
#if SWIFT_OBJC_INTEROP
146+
if (auto mangledName = getObjCClassOrProtocolName(Node))
147+
return Builder.createObjCClassType(mangledName->str());
148+
#endif
149+
LLVM_FALLTHROUGH;
150+
}
115151
case NodeKind::Enum:
116152
case NodeKind::Structure:
117153
case NodeKind::TypeAlias: // This can show up for imported Clang decls.
@@ -125,6 +161,14 @@ class TypeDecoder {
125161
return Builder.createNominalType(typeDecl, parent);
126162
}
127163
case NodeKind::BoundGenericClass:
164+
{
165+
#if SWIFT_OBJC_INTEROP
166+
if (Node->getNumChildren() == 2)
167+
if (auto mangledName = getObjCClassOrProtocolName(Node->getChild(0)))
168+
return Builder.createObjCClassType(mangledName->str());
169+
#endif
170+
LLVM_FALLTHROUGH;
171+
}
128172
case NodeKind::BoundGenericEnum:
129173
case NodeKind::BoundGenericStructure:
130174
case NodeKind::BoundGenericOtherNominalType: {
@@ -528,6 +572,11 @@ class TypeDecoder {
528572
&& node->getKind() != NodeKind::ProtocolSymbolicReference)
529573
return BuiltProtocolDecl();
530574

575+
#if SWIFT_OBJC_INTEROP
576+
if (auto objcProtocolName = getObjCClassOrProtocolName(node))
577+
return Builder.createObjCProtocolDecl(objcProtocolName->str());
578+
#endif
579+
531580
return Builder.createProtocolDecl(node);
532581
}
533582

include/swift/Reflection/TypeRef.h

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,11 @@ class FunctionTypeRef final : public TypeRef {
386386
};
387387

388388
class ProtocolCompositionTypeRef final : public TypeRef {
389-
std::vector<const NominalTypeRef *> Protocols;
389+
std::vector<const TypeRef *> Protocols;
390390
const TypeRef *Superclass;
391391
bool HasExplicitAnyObject;
392392

393-
static TypeRefID Profile(std::vector<const NominalTypeRef *> Protocols,
393+
static TypeRefID Profile(std::vector<const TypeRef *> Protocols,
394394
const TypeRef *Superclass,
395395
bool HasExplicitAnyObject) {
396396
TypeRefID ID;
@@ -403,7 +403,7 @@ class ProtocolCompositionTypeRef final : public TypeRef {
403403
}
404404

405405
public:
406-
ProtocolCompositionTypeRef(std::vector<const NominalTypeRef *> Protocols,
406+
ProtocolCompositionTypeRef(std::vector<const TypeRef *> Protocols,
407407
const TypeRef *Superclass,
408408
bool HasExplicitAnyObject)
409409
: TypeRef(TypeRefKind::ProtocolComposition),
@@ -412,13 +412,14 @@ class ProtocolCompositionTypeRef final : public TypeRef {
412412

413413
template <typename Allocator>
414414
static const ProtocolCompositionTypeRef *
415-
create(Allocator &A, std::vector<const NominalTypeRef *> Protocols,
415+
create(Allocator &A, std::vector<const TypeRef *> Protocols,
416416
const TypeRef *Superclass, bool HasExplicitAnyObject) {
417417
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Protocols,
418418
Superclass, HasExplicitAnyObject);
419419
}
420420

421-
const std::vector<const NominalTypeRef *> &getProtocols() const {
421+
// These are either NominalTypeRef or ObjCProtocolTypeRef.
422+
const std::vector<const TypeRef *> &getProtocols() const {
422423
return Protocols;
423424
}
424425

@@ -633,6 +634,36 @@ class ObjCClassTypeRef final : public TypeRef {
633634
}
634635
};
635636

637+
class ObjCProtocolTypeRef final : public TypeRef {
638+
std::string Name;
639+
static const ObjCProtocolTypeRef *UnnamedSingleton;
640+
641+
static TypeRefID Profile(const std::string &Name) {
642+
TypeRefID ID;
643+
ID.addString(Name);
644+
return ID;
645+
}
646+
public:
647+
ObjCProtocolTypeRef(const std::string &Name)
648+
: TypeRef(TypeRefKind::ObjCProtocol), Name(Name) {}
649+
650+
static const ObjCProtocolTypeRef *getUnnamed();
651+
652+
template <typename Allocator>
653+
static const ObjCProtocolTypeRef *create(Allocator &A,
654+
const std::string &Name) {
655+
FIND_OR_CREATE_TYPEREF(A, ObjCProtocolTypeRef, Name);
656+
}
657+
658+
const std::string &getName() const {
659+
return Name;
660+
}
661+
662+
static bool classof(const TypeRef *TR) {
663+
return TR->getKind() == TypeRefKind::ObjCProtocol;
664+
}
665+
};
666+
636667
class OpaqueTypeRef final : public TypeRef {
637668
static const OpaqueTypeRef *Singleton;
638669

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class TypeRefBuilder {
160160
public:
161161
using BuiltType = const TypeRef *;
162162
using BuiltNominalTypeDecl = Optional<std::string>;
163-
using BuiltProtocolDecl = Optional<std::string>;
163+
using BuiltProtocolDecl = Optional<std::pair<std::string, bool /*isObjC*/>>;
164164

165165
TypeRefBuilder();
166166

@@ -214,9 +214,14 @@ class TypeRefBuilder {
214214
return Demangle::mangleNode(node);
215215
}
216216

217-
Optional<std::string>
217+
BuiltProtocolDecl
218218
createProtocolDecl(const Demangle::NodePointer &node) {
219-
return Demangle::mangleNode(node);
219+
return std::make_pair(Demangle::mangleNode(node), false);
220+
}
221+
222+
BuiltProtocolDecl
223+
createObjCProtocolDecl(std::string &&name) {
224+
return std::make_pair(name, true);
220225
}
221226

222227
Optional<std::string> createNominalTypeDecl(std::string &&mangledName) {
@@ -265,9 +270,15 @@ class TypeRefBuilder {
265270
createProtocolCompositionType(ArrayRef<BuiltProtocolDecl> protocols,
266271
BuiltType superclass,
267272
bool isClassBound) {
268-
std::vector<const NominalTypeRef *> protocolRefs;
273+
std::vector<const TypeRef *> protocolRefs;
269274
for (const auto &protocol : protocols) {
270-
protocolRefs.push_back(createNominalType(protocol));
275+
if (!protocol)
276+
continue;
277+
278+
if (protocol->second)
279+
protocolRefs.push_back(createObjCProtocolType(protocol->first));
280+
else
281+
protocolRefs.push_back(createNominalType(protocol->first));
271282
}
272283

273284
return ProtocolCompositionTypeRef::create(*this, protocolRefs, superclass,
@@ -292,8 +303,12 @@ class TypeRefBuilder {
292303
const DependentMemberTypeRef *
293304
createDependentMemberType(const std::string &member,
294305
const TypeRef *base,
295-
Optional<std::string> protocol) {
296-
return DependentMemberTypeRef::create(*this, member, base, *protocol);
306+
BuiltProtocolDecl protocol) {
307+
// Objective-C protocols don't have dependent types.
308+
if (protocol->second)
309+
return nullptr;
310+
return DependentMemberTypeRef::create(*this, member, base,
311+
protocol->first);
297312
}
298313

299314
#define REF_STORAGE(Name, ...) \
@@ -306,13 +321,18 @@ class TypeRefBuilder {
306321
return SILBoxTypeRef::create(*this, base);
307322
}
308323

324+
const ObjCClassTypeRef *getUnnamedObjCClassType() {
325+
return createObjCClassType("");
326+
}
327+
309328
const ObjCClassTypeRef *
310-
createObjCClassType(const std::string &mangledName) {
311-
return ObjCClassTypeRef::create(*this, mangledName);
329+
createObjCClassType(const std::string &name) {
330+
return ObjCClassTypeRef::create(*this, name);
312331
}
313332

314-
const ObjCClassTypeRef *getUnnamedObjCClassType() {
315-
return createObjCClassType("");
333+
const ObjCProtocolTypeRef *
334+
createObjCProtocolType(const std::string &name) {
335+
return ObjCProtocolTypeRef::create(*this, name);
316336
}
317337

318338
const ForeignClassTypeRef *

include/swift/Reflection/TypeRefs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ TYPEREF(GenericTypeParameter, TypeRef)
2828
TYPEREF(DependentMember, TypeRef)
2929
TYPEREF(ForeignClass, TypeRef)
3030
TYPEREF(ObjCClass, TypeRef)
31+
TYPEREF(ObjCProtocol, TypeRef)
3132
TYPEREF(Opaque, TypeRef)
3233
#define REF_STORAGE(Name, ...) \
3334
TYPEREF(Name##Storage, TypeRef)

include/swift/Remote/MetadataReader.h

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -498,18 +498,39 @@ class MetadataReader {
498498
#if SWIFT_OBJC_INTEROP
499499
// Check whether we have an Objective-C protocol.
500500
if (ProtocolAddress.isObjC()) {
501-
auto MangledNameStr =
501+
auto Name =
502502
readObjCProtocolName(ProtocolAddress.getObjCProtocol());
503+
StringRef NameStr(Name);
504+
505+
// If this is a Swift-defined protocol, demangle it.
506+
if (NameStr.startswith("_TtP")) {
507+
Demangle::Context DCtx;
508+
auto Demangled = DCtx.demangleSymbolAsNode(NameStr);
509+
if (!Demangled)
510+
return BuiltType();
511+
512+
// FIXME: This appears in _swift_buildDemanglingForMetadata().
513+
while (Demangled->getKind() == Node::Kind::Global ||
514+
Demangled->getKind() == Node::Kind::TypeMangling ||
515+
Demangled->getKind() == Node::Kind::Type ||
516+
Demangled->getKind() == Node::Kind::ProtocolList ||
517+
Demangled->getKind() == Node::Kind::TypeList ||
518+
Demangled->getKind() == Node::Kind::Type) {
519+
if (Demangled->getNumChildren() != 1)
520+
return BuiltType();
521+
Demangled = Demangled->getFirstChild();
522+
}
523+
524+
auto Protocol = Builder.createProtocolDecl(Demangled);
525+
if (!Protocol)
526+
return BuiltType();
527+
528+
Protocols.push_back(Protocol);
529+
continue;
530+
}
503531

504-
StringRef MangledName =
505-
Demangle::dropSwiftManglingPrefix(MangledNameStr);
506-
507-
Demangle::Context DCtx;
508-
auto Demangled = DCtx.demangleTypeAsNode(MangledName);
509-
if (!Demangled)
510-
return BuiltType();
511-
512-
auto Protocol = Builder.createProtocolDecl(Demangled);
532+
// Otherwise, this is an imported protocol.
533+
auto Protocol = Builder.createObjCProtocolDecl(NameStr);
513534
if (!Protocol)
514535
return BuiltType();
515536

@@ -518,6 +539,7 @@ class MetadataReader {
518539
}
519540
#endif
520541

542+
// Swift-native protocol.
521543
Demangle::Demangler Dem;
522544
auto Demangled = readDemanglingForContextDescriptor(
523545
ProtocolAddress.getSwiftProtocol(), Dem);

include/swift/RemoteAST/RemoteAST.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ class RemoteASTContext {
221221
Type staticType);
222222
};
223223

224+
Type getTypeForMangling(ASTContext &ctx,
225+
StringRef mangling);
226+
224227
} // end namespace remoteAST
225228
} // end namespace swift
226229

lib/IRGen/GenReflection.cpp

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -202,21 +202,16 @@ class ReflectionMetadataBuilder {
202202
if (IGM.getSwiftModule()->isStdlibModule() && isa<BuiltinType>(t))
203203
IGM.BuiltinTypes.insert(t);
204204

205-
// We need size/alignment information for imported value types,
206-
// so emit builtin descriptors for them.
205+
// We need size/alignment information for imported structs and
206+
// enums, so emit builtin descriptors for them.
207207
//
208208
// In effect they're treated like an opaque blob, which is OK
209209
// for now, at least until we want to import C++ types or
210210
// something like that.
211-
//
212-
// Classes and protocols go down a different path.
213211
if (auto Nominal = t->getAnyNominal())
214212
if (Nominal->hasClangNode()) {
215-
if (auto CD = dyn_cast<ClassDecl>(Nominal))
216-
IGM.ImportedClasses.insert(CD);
217-
else if (auto PD = dyn_cast<ProtocolDecl>(Nominal))
218-
IGM.ImportedProtocols.insert(PD);
219-
else
213+
if (isa<StructDecl>(Nominal) ||
214+
isa<EnumDecl>(Nominal))
220215
IGM.OpaqueTypes.insert(Nominal);
221216
}
222217
});
@@ -386,14 +381,6 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
386381
B.addInt16(uint16_t(kind));
387382
B.addInt16(fieldRecordSize);
388383

389-
// Imported classes don't need field descriptors
390-
if (NTD->hasClangNode() && isa<ClassDecl>(NTD)) {
391-
B.addInt32(0);
392-
return;
393-
}
394-
395-
assert(!NTD->hasClangNode() || isa<StructDecl>(NTD));
396-
397384
auto properties = NTD->getStoredProperties();
398385
B.addInt32(std::distance(properties.begin(), properties.end()));
399386
for (auto property : properties)
@@ -453,11 +440,7 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
453440
}
454441

455442
void layout() override {
456-
if (NTD->hasClangNode() &&
457-
!isa<ClassDecl>(NTD) &&
458-
!isa<StructDecl>(NTD) &&
459-
!isa<ProtocolDecl>(NTD))
460-
return;
443+
assert(!NTD->hasClangNode() || isa<StructDecl>(NTD));
461444

462445
PrettyStackTraceDecl DebugStack("emitting field type metadata", NTD);
463446
addNominalRef(NTD);
@@ -949,12 +932,6 @@ void IRGenModule::emitBuiltinReflectionMetadata() {
949932
BuiltinTypes.insert(anyMetatype);
950933
}
951934

952-
for (auto CD : ImportedClasses)
953-
emitFieldMetadataRecord(CD);
954-
955-
for (auto PD : ImportedProtocols)
956-
emitFieldMetadataRecord(PD);
957-
958935
for (auto SD : ImportedStructs)
959936
emitFieldMetadataRecord(SD);
960937

lib/IRGen/IRGenModule.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,12 +1045,6 @@ class IRGenModule {
10451045
/// without knowledge of their contents. This includes imported structs
10461046
/// and fixed-size multi-payload enums.
10471047
llvm::SetVector<const NominalTypeDecl *> OpaqueTypes;
1048-
/// Imported classes referenced by types in this module when emitting
1049-
/// reflection metadata.
1050-
llvm::SetVector<const ClassDecl *> ImportedClasses;
1051-
/// Imported protocols referenced by types in this module when emitting
1052-
/// reflection metadata.
1053-
llvm::SetVector<const ProtocolDecl *> ImportedProtocols;
10541048
/// Imported structs referenced by types in this module when emitting
10551049
/// reflection metadata.
10561050
llvm::SetVector<const StructDecl *> ImportedStructs;

0 commit comments

Comments
 (0)