Skip to content

Commit 1bdd092

Browse files
committed
[PrintAsObjC] Use C names when printing imported structs.
(and enums) Previously this part of the compiler assumed that any imported struct or enum would have the same name as it does in C, which is no longer true. Part of rdar://problem/26372925
1 parent ca97762 commit 1bdd092

File tree

3 files changed

+73
-11
lines changed

3 files changed

+73
-11
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,25 @@ namespace {
7373
};
7474
}
7575

76-
static Identifier getNameForObjC(const ValueDecl *VD,
77-
CustomNamesOnly_t customNamesOnly = Normal) {
78-
assert(isa<ClassDecl>(VD) || isa<ProtocolDecl>(VD)
79-
|| isa<EnumDecl>(VD) || isa<EnumElementDecl>(VD));
76+
static StringRef getNameForObjC(const ValueDecl *VD,
77+
CustomNamesOnly_t customNamesOnly = Normal) {
78+
assert(isa<ClassDecl>(VD) || isa<ProtocolDecl>(VD) || isa<StructDecl>(VD) ||
79+
isa<EnumDecl>(VD) || isa<EnumElementDecl>(VD));
8080
if (auto objc = VD->getAttrs().getAttribute<ObjCAttr>()) {
8181
if (auto name = objc->getName()) {
8282
assert(name->getNumSelectorPieces() == 1);
83-
return name->getSelectorPieces().front();
83+
return name->getSelectorPieces().front().str();
8484
}
8585
}
8686

87-
return customNamesOnly ? Identifier() : VD->getName();
87+
if (customNamesOnly)
88+
return StringRef();
89+
90+
if (auto clangDecl = dyn_cast_or_null<clang::NamedDecl>(VD->getClangDecl()))
91+
if (const clang::IdentifierInfo *II = clangDecl->getIdentifier())
92+
return II->getName();
93+
94+
return VD->getName().str();
8895
}
8996

9097

@@ -187,7 +194,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
187194
void visitClassDecl(ClassDecl *CD) {
188195
printDocumentationComment(CD);
189196

190-
Identifier customName = getNameForObjC(CD, CustomNamesOnly);
197+
StringRef customName = getNameForObjC(CD, CustomNamesOnly);
191198
if (customName.empty()) {
192199
llvm::SmallString<32> scratch;
193200
os << "SWIFT_CLASS(\"" << CD->getObjCRuntimeName(scratch) << "\")\n"
@@ -219,7 +226,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
219226
void visitProtocolDecl(ProtocolDecl *PD) {
220227
printDocumentationComment(PD);
221228

222-
Identifier customName = getNameForObjC(PD, CustomNamesOnly);
229+
StringRef customName = getNameForObjC(PD, CustomNamesOnly);
223230
if (customName.empty()) {
224231
llvm::SmallString<32> scratch;
225232
os << "SWIFT_PROTOCOL(\"" << PD->getObjCRuntimeName(scratch) << "\")\n"
@@ -240,7 +247,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
240247
void visitEnumDecl(EnumDecl *ED) {
241248
printDocumentationComment(ED);
242249
os << "typedef ";
243-
Identifier customName = getNameForObjC(ED, CustomNamesOnly);
250+
StringRef customName = getNameForObjC(ED, CustomNamesOnly);
244251
if (customName.empty()) {
245252
os << "SWIFT_ENUM(";
246253
} else {
@@ -260,7 +267,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
260267
// Print the cases as the concatenation of the enum name with the case
261268
// name.
262269
os << " ";
263-
Identifier customEltName = getNameForObjC(Elt, CustomNamesOnly);
270+
StringRef customEltName = getNameForObjC(Elt, CustomNamesOnly);
264271
if (customEltName.empty()) {
265272
if (customName.empty()) {
266273
os << ED->getName();
@@ -1014,7 +1021,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
10141021
return;
10151022

10161023
maybePrintTagKeyword(SD);
1017-
os << SD->getName();
1024+
os << getNameForObjC(SD);
10181025
}
10191026

10201027
/// Print a collection element type using Objective-C generics syntax.

test/PrintAsObjC/Inputs/swift_name.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// This file is meant to be used with the mock SDK, not the real one.
2+
#import <Foundation.h>
3+
4+
#define SWIFT_NAME(x) __attribute__((swift_name(#x)))
5+
6+
typedef NSString *ABCStringAlias SWIFT_NAME(ZZStringAlias);
7+
struct ABCPoint {
8+
int x;
9+
int y;
10+
} SWIFT_NAME(ZZPoint);
11+
enum ABCAlignment {
12+
ABCAlignmentLeft,
13+
ABCAlignmentRight
14+
} SWIFT_NAME(ZZAlignment);
15+
16+
SWIFT_NAME(ZZClass)
17+
@interface ABCClass : NSObject
18+
@end
19+
20+
SWIFT_NAME(ZZProto)
21+
@protocol ABCProto
22+
@end

test/PrintAsObjC/swift_name.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Please keep this file in alphabetical order!
2+
3+
// REQUIRES: objc_interop
4+
5+
// RUN: rm -rf %t && mkdir %t
6+
7+
// FIXME: BEGIN -enable-source-import hackaround
8+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift
9+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
10+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
11+
// FIXME: END -enable-source-import hackaround
12+
13+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/Inputs/swift_name.h -emit-module -o %t %s
14+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/Inputs/swift_name.h -parse-as-library %t/swift_name.swiftmodule -parse -emit-objc-header-path %t/swift_name.h
15+
16+
// RUN: FileCheck %s < %t/swift_name.h
17+
// RUN: %check-in-clang %t/swift_name.h
18+
19+
import Foundation
20+
21+
// CHECK-LABEL: @interface Test : NSObject
22+
// CHECK-NEXT: - (NSArray<ABCStringAlias> * _Nonnull)makeArray:(ABCStringAlias _Nonnull)_;
23+
// CHECK-NEXT: - (void)usePoint:(struct ABCPoint)_;
24+
// CHECK-NEXT: - (void)useAlignment:(enum ABCAlignment)_;
25+
// CHECK-NEXT: - (NSArray<id <ABCProto>> * _Nonnull)useObjects:(ABCClass * _Nonnull)_;
26+
// CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
27+
// CHECK-NEXT: @end
28+
class Test : NSObject {
29+
func makeArray(_: ZZStringAlias) -> [ZZStringAlias] { return [] }
30+
func usePoint(_: ZZPoint) {}
31+
func useAlignment(_: ZZAlignment) {}
32+
func useObjects(_: ZZClass) -> [ZZProto] { return [] }
33+
}

0 commit comments

Comments
 (0)