Skip to content

Commit 33c7326

Browse files
authored
Merge pull request #70731 from beccadax/dont-let-labels-define-you
Make @_cdecl @implementation support __asm__
2 parents 7cccbcc + 85ea884 commit 33c7326

File tree

4 files changed

+62
-28
lines changed

4 files changed

+62
-28
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,13 +1041,44 @@ bool SILDeclRef::isBackDeploymentThunk() const {
10411041
}
10421042

10431043
/// Use the Clang importer to mangle a Clang declaration.
1044-
static void mangleClangDecl(raw_ostream &buffer,
1045-
const clang::NamedDecl *clangDecl,
1046-
ASTContext &ctx) {
1044+
static void mangleClangDeclViaImporter(raw_ostream &buffer,
1045+
const clang::NamedDecl *clangDecl,
1046+
ASTContext &ctx) {
10471047
auto *importer = static_cast<ClangImporter *>(ctx.getClangModuleLoader());
10481048
importer->getMangledName(buffer, clangDecl);
10491049
}
10501050

1051+
static std::string mangleClangDecl(Decl *decl, bool isForeign) {
1052+
auto clangDecl = decl->getClangDecl();
1053+
1054+
if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) {
1055+
if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) {
1056+
std::string s(1, '\01');
1057+
s += asmLabel->getLabel();
1058+
return s;
1059+
} else if (namedClangDecl->hasAttr<clang::OverloadableAttr>() ||
1060+
decl->getASTContext().LangOpts.EnableCXXInterop) {
1061+
std::string storage;
1062+
llvm::raw_string_ostream SS(storage);
1063+
mangleClangDeclViaImporter(SS, namedClangDecl, decl->getASTContext());
1064+
return SS.str();
1065+
}
1066+
return namedClangDecl->getName().str();
1067+
} else if (auto objcDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
1068+
if (objcDecl->isDirectMethod() && isForeign) {
1069+
std::string storage;
1070+
llvm::raw_string_ostream SS(storage);
1071+
clang::ASTContext &ctx = clangDecl->getASTContext();
1072+
std::unique_ptr<clang::MangleContext> mangler(ctx.createMangleContext());
1073+
mangler->mangleObjCMethodName(objcDecl, SS, /*includePrefixByte=*/true,
1074+
/*includeCategoryNamespace=*/false);
1075+
return SS.str();
1076+
}
1077+
}
1078+
1079+
return "";
1080+
}
1081+
10511082
std::string SILDeclRef::mangle(ManglingKind MKind) const {
10521083
using namespace Mangle;
10531084
ASTMangler mangler;
@@ -1073,32 +1104,11 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
10731104
// As a special case, Clang functions and globals don't get mangled at all
10741105
// - except \c objc_direct decls.
10751106
if (hasDecl()) {
1076-
if (auto clangDecl = getDecl()->getClangDecl()) {
1107+
if (getDecl()->getClangDecl()) {
10771108
if (!isForeignToNativeThunk() && !isNativeToForeignThunk()) {
1078-
if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) {
1079-
if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) {
1080-
std::string s(1, '\01');
1081-
s += asmLabel->getLabel();
1082-
return s;
1083-
} else if (namedClangDecl->hasAttr<clang::OverloadableAttr>() ||
1084-
getDecl()->getASTContext().LangOpts.EnableCXXInterop) {
1085-
std::string storage;
1086-
llvm::raw_string_ostream SS(storage);
1087-
mangleClangDecl(SS, namedClangDecl, getDecl()->getASTContext());
1088-
return SS.str();
1089-
}
1090-
return namedClangDecl->getName().str();
1091-
} else if (auto objcDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
1092-
if (objcDecl->isDirectMethod() && isForeign) {
1093-
std::string storage;
1094-
llvm::raw_string_ostream SS(storage);
1095-
clang::ASTContext &ctx = clangDecl->getASTContext();
1096-
std::unique_ptr<clang::MangleContext> mangler(ctx.createMangleContext());
1097-
mangler->mangleObjCMethodName(objcDecl, SS, /*includePrefixByte=*/true,
1098-
/*includeCategoryNamespace=*/false);
1099-
return SS.str();
1100-
}
1101-
}
1109+
auto clangMangling = mangleClangDecl(getDecl(), isForeign);
1110+
if (!clangMangling.empty())
1111+
return clangMangling;
11021112
}
11031113
}
11041114
}
@@ -1156,6 +1166,13 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
11561166
// Use a given cdecl name for native-to-foreign thunks.
11571167
if (auto CDeclA = getDecl()->getAttrs().getAttribute<CDeclAttr>())
11581168
if (isNativeToForeignThunk()) {
1169+
// If this is an @implementation @_cdecl, mangle it like the clang
1170+
// function it implements.
1171+
if (auto objcInterface = getDecl()->getImplementedObjCDecl()) {
1172+
auto clangMangling = mangleClangDecl(objcInterface, isForeign);
1173+
if (!clangMangling.empty())
1174+
return clangMangling;
1175+
}
11591176
return CDeclA->Name.str();
11601177
}
11611178

test/IRGen/Inputs/objc_implementation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
@end
2626

2727
extern void implFunc(int param);
28+
extern void implFuncCName(int param) __asm__("_implFuncAsmName");
2829

2930

3031
@interface NoImplClass

test/IRGen/objc_implementation.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ - (void)category1Method:(int)value {
2828

2929
@end
3030

31+
void implFunc(int param) {
32+
printf("implFunc");
33+
}
34+
35+
void implFuncCName(int param) {
36+
printf("implFuncCName");
37+
}

test/IRGen/objc_implementation.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,14 @@ open class SwiftSubclass: ImplClass {
142142
@_objcImplementation @_cdecl("implFunc")
143143
public func implFunc(_ param: Int32) {}
144144

145+
@_objcImplementation @_cdecl("implFuncCName")
146+
public func implFuncCName(_ param: Int32) {}
147+
145148
public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
146149
impl.mainMethod(0)
147150
swiftSub.mainMethod(1)
148151
implFunc(2)
152+
implFuncCName(3)
149153
}
150154

151155
// Swift calling convention -[ImplClass init]
@@ -248,6 +252,11 @@ public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
248252
// FIXME: We'd like this to be internal or hidden, not public.
249253
// CHECK: define swiftcc void @"$s19objc_implementation8implFuncyys5Int32VF"
250254

255+
// inplFuncCName(_:)
256+
// CHECK-LABEL: define void @"\01_implFuncAsmName"
257+
// FIXME: We'd like this to be internal or hidden, not public.
258+
// CHECK: define swiftcc void @"$s19objc_implementation13implFuncCNameyys5Int32VF"
259+
251260
// fn(impl:swiftSub:)
252261
// CHECK-LABEL: define swiftcc void @"$s19objc_implementation2fn4impl8swiftSubySo9ImplClassC_AA13SwiftSubclassCtF"
253262
// CHECK: [[SEL_1:%[^ ]+]] = load ptr, ptr @"\01L_selector(mainMethod:)", align 8

0 commit comments

Comments
 (0)