Skip to content

Commit f6c7440

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

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
@@ -4151,14 +4151,16 @@ namespace {
41514151
/// selector.
41524152
///
41534153
/// The importer should use this rather than adding the attribute directly.
4154-
void addObjCAttribute(ValueDecl *decl, std::optional<ObjCSelector> name) {
4154+
void addObjCAttribute(Decl *decl, std::optional<ObjCSelector> name) {
41554155
auto &ctx = Impl.SwiftContext;
41564156
if (name) {
41574157
decl->getAttrs().add(ObjCAttr::create(ctx, name,
41584158
/*implicitName=*/true));
41594159
}
4160-
decl->setIsObjC(true);
4161-
decl->setIsDynamic(true);
4160+
if (auto VD = dyn_cast<ValueDecl>(decl)) {
4161+
VD->setIsObjC(true);
4162+
VD->setIsDynamic(true);
4163+
}
41624164

41634165
// If the declaration we attached the 'objc' attribute to is within a
41644166
// type, record it in the type.
@@ -4176,7 +4178,7 @@ namespace {
41764178
/// selector.
41774179
///
41784180
/// The importer should use this rather than adding the attribute directly.
4179-
void addObjCAttribute(ValueDecl *decl, Identifier name) {
4181+
void addObjCAttribute(Decl *decl, Identifier name) {
41804182
addObjCAttribute(decl, ObjCSelector(Impl.SwiftContext, 0, name));
41814183
}
41824184

@@ -4797,6 +4799,11 @@ namespace {
47974799
objcClass->getDeclaredType());
47984800
Impl.SwiftContext.evaluator.cacheOutput(ExtendedNominalRequest{result},
47994801
std::move(objcClass));
4802+
4803+
Identifier categoryName;
4804+
if (!decl->getName().empty())
4805+
categoryName = Impl.SwiftContext.getIdentifier(decl->getName());
4806+
addObjCAttribute(result, categoryName);
48004807

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

0 commit comments

Comments
 (0)