Skip to content

Commit 07b2b9a

Browse files
committed
[NFC] Add @objc to imported ObjC categories
This contains the category name, if there is one.
1 parent c3225b0 commit 07b2b9a

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

lib/AST/Decl.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3707,6 +3707,29 @@ void ValueDecl::setIsObjC(bool value) {
37073707
LazySemanticInfo.isObjC = value;
37083708
}
37093709

3710+
Identifier ExtensionDecl::getObjCCategoryName() const {
3711+
// If there's an @objc attribute, it's authoritative. (ClangImporter
3712+
// attaches one automatically.)
3713+
if (auto objcAttr = getAttrs().getAttribute<ObjCAttr>(/*AllowInvalid*/true)) {
3714+
if (objcAttr->hasName() && objcAttr->getName()->getNumArgs() == 0)
3715+
return objcAttr->getName()->getSimpleName();
3716+
3717+
return Identifier();
3718+
}
3719+
3720+
// Fall back to @_objcImplementation attribute.
3721+
if (auto attr =
3722+
getAttrs().getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true)) {
3723+
if (!attr->isCategoryNameInvalid())
3724+
return attr->CategoryName;
3725+
3726+
return Identifier();
3727+
}
3728+
3729+
// Not a category, evidently.
3730+
return Identifier();
3731+
}
3732+
37103733
bool ValueDecl::isSemanticallyFinal() const {
37113734
// Actor types are semantically final.
37123735
if (auto classDecl = dyn_cast<ClassDecl>(this)) {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5969,32 +5969,6 @@ struct OrderDecls {
59695969
};
59705970
}
59715971

5972-
Identifier ExtensionDecl::getObjCCategoryName() const {
5973-
// Could it be an imported category?
5974-
if (!hasClangNode()) {
5975-
// Nope, not imported. Is it an @implementation extension?
5976-
auto attr = getAttrs()
5977-
.getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
5978-
if (attr && !attr->isCategoryNameInvalid())
5979-
return attr->CategoryName;
5980-
5981-
return Identifier();
5982-
}
5983-
5984-
auto category = dyn_cast<clang::ObjCCategoryDecl>(getClangDecl());
5985-
if (!category)
5986-
// Nope, not a category.
5987-
return Identifier();
5988-
5989-
// We'll look for an implementation with this category name.
5990-
auto clangCategoryName = category->getName();
5991-
if (clangCategoryName.empty())
5992-
// Class extension (has an empty name).
5993-
return Identifier();
5994-
5995-
return getASTContext().getIdentifier(clangCategoryName);
5996-
}
5997-
59985972
static ObjCInterfaceAndImplementation
59995973
constructResult(const llvm::TinyPtrVector<Decl *> &interfaces,
60005974
llvm::TinyPtrVector<Decl *> &impls,

lib/ClangImporter/ImportDecl.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4132,14 +4132,16 @@ namespace {
41324132
/// selector.
41334133
///
41344134
/// The importer should use this rather than adding the attribute directly.
4135-
void addObjCAttribute(ValueDecl *decl, std::optional<ObjCSelector> name) {
4135+
void addObjCAttribute(Decl *decl, std::optional<ObjCSelector> name) {
41364136
auto &ctx = Impl.SwiftContext;
41374137
if (name) {
41384138
decl->getAttrs().add(ObjCAttr::create(ctx, name,
41394139
/*implicitName=*/true));
41404140
}
4141-
decl->setIsObjC(true);
4142-
decl->setIsDynamic(true);
4141+
if (auto VD = dyn_cast<ValueDecl>(decl)) {
4142+
VD->setIsObjC(true);
4143+
VD->setIsDynamic(true);
4144+
}
41434145

41444146
// If the declaration we attached the 'objc' attribute to is within a
41454147
// type, record it in the type.
@@ -4157,7 +4159,7 @@ namespace {
41574159
/// selector.
41584160
///
41594161
/// The importer should use this rather than adding the attribute directly.
4160-
void addObjCAttribute(ValueDecl *decl, Identifier name) {
4162+
void addObjCAttribute(Decl *decl, Identifier name) {
41614163
addObjCAttribute(decl, ObjCSelector(Impl.SwiftContext, 0, name));
41624164
}
41634165

@@ -4778,6 +4780,11 @@ namespace {
47784780
objcClass->getDeclaredType());
47794781
Impl.SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{result},
47804782
std::move(objcClass));
4783+
4784+
Identifier categoryName;
4785+
if (!decl->getName().empty())
4786+
categoryName = Impl.SwiftContext.getIdentifier(decl->getName());
4787+
addObjCAttribute(result, categoryName);
47814788

47824789
// Create the extension declaration and record it.
47834790
objcClass->addExtension(result);

0 commit comments

Comments
 (0)