Skip to content

Commit 58950a5

Browse files
authored
Merge pull request #30250 from jckarter/mangle-objc-runtime-names
IRGen: Generate runtime type manglings using ObjC runtime names.
2 parents 2cc9446 + fe11864 commit 58950a5

File tree

5 files changed

+53
-10
lines changed

5 files changed

+53
-10
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class ASTMangler : public Mangler {
3939
bool OptimizeProtocolNames = true;
4040

4141
/// If enabled, use Objective-C runtime names when mangling @objc Swift
42-
/// protocols.
43-
bool UseObjCProtocolNames = false;
42+
/// protocols and classes.
43+
bool UseObjCRuntimeNames = false;
4444

4545
/// If enabled, non-canonical types are allowed and type alias types get a
4646
/// special mangling.

lib/AST/ASTMangler.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ void ASTMangler::appendDeclName(const ValueDecl *decl) {
699699
break;
700700
}
701701
} else if (auto objCName =
702-
getOverriddenSwiftProtocolObjCName(decl, UseObjCProtocolNames)) {
702+
getOverriddenSwiftProtocolObjCName(decl, UseObjCRuntimeNames)) {
703703
// @objc Swift protocols should be mangled as Objective-C protocols,
704704
// so append the Objective-C runtime name.
705705
appendIdentifier(*objCName);
@@ -1298,7 +1298,7 @@ void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) {
12981298
genericArgs = boundType->getGenericArgs();
12991299
if (Type parent = boundType->getParent()) {
13001300
GenericTypeDecl *decl = boundType->getAnyGeneric();
1301-
if (!getSpecialManglingContext(decl, UseObjCProtocolNames))
1301+
if (!getSpecialManglingContext(decl, UseObjCRuntimeNames))
13021302
appendBoundGenericArgs(parent->getDesugaredType(), isFirstArgList);
13031303
}
13041304
}
@@ -1610,7 +1610,7 @@ ASTMangler::getSpecialManglingContext(const ValueDecl *decl,
16101610
/// This is the top-level entrypoint for mangling <context>.
16111611
void ASTMangler::appendContextOf(const ValueDecl *decl) {
16121612
// Check for a special mangling context.
1613-
if (auto context = getSpecialManglingContext(decl, UseObjCProtocolNames)) {
1613+
if (auto context = getSpecialManglingContext(decl, UseObjCRuntimeNames)) {
16141614
switch (*context) {
16151615
case ClangImporterContext:
16161616
return appendOperator("SC");
@@ -1857,7 +1857,10 @@ void ASTMangler::appendProtocolName(const ProtocolDecl *protocol,
18571857

18581858
appendContextOf(protocol);
18591859
auto *clangDecl = protocol->getClangDecl();
1860-
if (auto *clangProto = cast_or_null<clang::ObjCProtocolDecl>(clangDecl))
1860+
auto clangProto = cast_or_null<clang::ObjCProtocolDecl>(clangDecl);
1861+
if (clangProto && UseObjCRuntimeNames)
1862+
appendIdentifier(clangProto->getObjCRuntimeNameAsString());
1863+
else if (clangProto)
18611864
appendIdentifier(clangProto->getName());
18621865
else
18631866
appendDeclName(protocol);
@@ -1928,15 +1931,25 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
19281931
if (!namedDecl)
19291932
return false;
19301933

1931-
appendIdentifier(namedDecl->getName());
1934+
// Mangle ObjC classes using their runtime names.
1935+
auto interface = dyn_cast<clang::ObjCInterfaceDecl>(namedDecl);
1936+
auto protocol = dyn_cast<clang::ObjCProtocolDecl>(namedDecl);
1937+
1938+
if (UseObjCRuntimeNames && interface) {
1939+
appendIdentifier(interface->getObjCRuntimeNameAsString());
1940+
} else if (UseObjCRuntimeNames && protocol) {
1941+
appendIdentifier(protocol->getObjCRuntimeNameAsString());
1942+
} else {
1943+
appendIdentifier(namedDecl->getName());
1944+
}
19321945

19331946
// The important distinctions to maintain here are Objective-C's various
19341947
// namespaces: protocols, tags (struct/enum/union), and unqualified names.
19351948
// We continue to mangle "class" the standard Swift way because it feels
19361949
// weird to call that an alias, but they're really in the same namespace.
1937-
if (isa<clang::ObjCInterfaceDecl>(namedDecl)) {
1950+
if (interface) {
19381951
appendOperator("C");
1939-
} else if (isa<clang::ObjCProtocolDecl>(namedDecl)) {
1952+
} else if (protocol) {
19401953
appendOperator("P");
19411954
} else if (isa<clang::TagDecl>(namedDecl)) {
19421955
// Note: This includes enums, but that's okay. A Clang enum is not always

lib/IRGen/IRGenMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ IRGenMangler::withSymbolicReferences(IRGenModule &IGM,
8383
llvm::function_ref<void ()> body) {
8484
Mod = IGM.getSwiftModule();
8585
OptimizeProtocolNames = false;
86-
UseObjCProtocolNames = true;
86+
UseObjCRuntimeNames = true;
8787

8888
llvm::SaveAndRestore<bool>
8989
AllowSymbolicReferencesLocally(AllowSymbolicReferences);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import Foundation;
2+
3+
__attribute__((objc_runtime_name("ObjCRuntimeNameIsDifferent")))
4+
@interface ObjCRuntimeNamed: NSObject
5+
6+
@end
7+
8+
__attribute__((objc_runtime_name("ObjCProtoRuntimeNameIsDifferent")))
9+
@protocol ObjCProtoRuntimeNamed
10+
11+
@end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -import-objc-header %S/Inputs/objc_runtime_name_clang_attr.h %s | %FileCheck %s
2+
// REQUIRES: objc_interop
3+
4+
// Use the runtime name for runtime instantiation
5+
// CHECK-LABEL: @"$sSo16ObjCRuntimeNamedCSgMD" = {{.*}}@"symbolic So26ObjCRuntimeNameIsDifferentCSg"
6+
public func getMetadata() -> Any.Type {
7+
return ObjCRuntimeNamed?.self
8+
}
9+
// CHECK-LABEL: @"$sSo21ObjCProtoRuntimeNamed_pSgMD" = {{.*}}@"symbolic So31ObjCProtoRuntimeNameIsDifferent_pSg"
10+
public func getMetadata2() -> Any.Type {
11+
return ObjCProtoRuntimeNamed?.self
12+
}
13+
14+
// Use the source name for symbols to avoid breaking ABI.
15+
// CHECK-LABEL: define{{.*}}3fooyySo16ObjCRuntimeNamedCF
16+
public func foo(_: ObjCRuntimeNamed) {}
17+
18+
// CHECK-LABEL: define{{.*}}3fooyySo21ObjCProtoRuntimeNamed_pF
19+
public func foo(_: ObjCProtoRuntimeNamed) {}

0 commit comments

Comments
 (0)