From b8407b3343457170e8317db1dc06ee5d0fbb9f68 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Thu, 1 Jun 2017 15:28:44 -0700 Subject: [PATCH] [PrintAsObjC] Handle the importer's compatibility typealiases. (#10042) These are TypeAliasDecls whose Clang nodes are not TypedefNameDecls. This worked all right for classes, but dropped the tag keyword (e.g. 'struct') for tag decls with names of their own, and didn't print any name at all for C types that used the typedef-for-anonymous-tag pattern. rdar://problem/32514335 --- lib/AST/SwiftNameTranslation.cpp | 3 ++- lib/PrintAsObjC/PrintAsObjC.cpp | 5 +++-- .../Inputs/custom-modules/NestedClass.apinotes | 8 ++++++++ test/PrintAsObjC/Inputs/custom-modules/NestedClass.h | 11 +++++++++++ test/PrintAsObjC/versioned.swift | 6 ++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/AST/SwiftNameTranslation.cpp b/lib/AST/SwiftNameTranslation.cpp index cf9aefcf98780..8cd2df6e20838 100644 --- a/lib/AST/SwiftNameTranslation.cpp +++ b/lib/AST/SwiftNameTranslation.cpp @@ -28,7 +28,8 @@ using namespace swift; StringRef swift::objc_translation:: getNameForObjC(const ValueDecl *VD, CustomNamesOnly_t customNamesOnly) { assert(isa(VD) || isa(VD) || isa(VD) || - isa(VD) || isa(VD)); + isa(VD) || isa(VD) || + isa(VD)); if (auto objc = VD->getAttrs().getAttribute()) { if (auto name = objc->getName()) { assert(name->getNumSelectorPieces() == 1); diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp index a95e869cefb50..c57ce3e8b919d 100644 --- a/lib/PrintAsObjC/PrintAsObjC.cpp +++ b/lib/PrintAsObjC/PrintAsObjC.cpp @@ -1370,7 +1370,8 @@ class ObjCPrinter : private DeclVisitor, if (alias->hasClangNode()) { if (auto *clangTypeDecl = dyn_cast(alias->getClangDecl())) { - os << clangTypeDecl->getName(); + maybePrintTagKeyword(alias); + os << getNameForObjC(alias); if (isClangPointerType(clangTypeDecl)) printNullability(optionalKind); @@ -1396,7 +1397,7 @@ class ObjCPrinter : private DeclVisitor, visitPart(alias->getUnderlyingTypeLoc().getType(), optionalKind); } - void maybePrintTagKeyword(const NominalTypeDecl *NTD) { + void maybePrintTagKeyword(const TypeDecl *NTD) { if (isa(NTD) && !NTD->hasClangNode()) { os << "enum "; return; diff --git a/test/PrintAsObjC/Inputs/custom-modules/NestedClass.apinotes b/test/PrintAsObjC/Inputs/custom-modules/NestedClass.apinotes index 1feb47efde858..4cbf4e7a3e5fd 100644 --- a/test/PrintAsObjC/Inputs/custom-modules/NestedClass.apinotes +++ b/test/PrintAsObjC/Inputs/custom-modules/NestedClass.apinotes @@ -4,3 +4,11 @@ SwiftVersions: Classes: - Name: InnerClass SwiftName: InnerClass + Tags: + - Name: InnerStruct + SwiftName: InnerStruct + Typedefs: + - Name: InnerAlias + SwiftName: InnerAlias + - Name: InnerAnonStruct + SwiftName: InnerAnonStruct diff --git a/test/PrintAsObjC/Inputs/custom-modules/NestedClass.h b/test/PrintAsObjC/Inputs/custom-modules/NestedClass.h index ea0f32707e47f..8997270435523 100644 --- a/test/PrintAsObjC/Inputs/custom-modules/NestedClass.h +++ b/test/PrintAsObjC/Inputs/custom-modules/NestedClass.h @@ -8,3 +8,14 @@ __attribute__((swift_name("Outer.Inner"))) @interface InnerClass : NSObject @end + +struct __attribute__((swift_name("Outer.InnerV"))) InnerStruct { + int value; +}; + +typedef struct { + int value; +} InnerAnonStruct __attribute__((swift_name("Outer.InnerAS"))); + +typedef int InnerAlias __attribute__((swift_name("Outer.InnerA"))); + diff --git a/test/PrintAsObjC/versioned.swift b/test/PrintAsObjC/versioned.swift index 46e2d8a0531e7..350180c21893c 100644 --- a/test/PrintAsObjC/versioned.swift +++ b/test/PrintAsObjC/versioned.swift @@ -22,6 +22,12 @@ import NestedClass @objc class UsesNestedClass : NSObject { // CHECK-NEXT: - (InnerClass * _Nullable)foo SWIFT_WARN_UNUSED_RESULT; @objc func foo() -> InnerClass? { return nil } + // CHECK-NEXT: - (void)fooStruct:(struct InnerStruct)_; + @objc func fooStruct(_: InnerStruct) {} + // CHECK-NEXT: - (void)fooAnonStruct:(InnerAnonStruct)_; + @objc func fooAnonStruct(_: InnerAnonStruct) {} + // CHECK-NEXT: - (void)fooAlias:(InnerAlias)_; + @objc func fooAlias(_: InnerAlias) {} // CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; }