@@ -1517,60 +1517,79 @@ void AttributeChecker::visitNonObjCAttr(NonObjCAttr *attr) {
15171517
15181518void AttributeChecker::
15191519visitObjCImplementationAttr (ObjCImplementationAttr *attr) {
1520- auto ED = cast <ExtensionDecl>(D);
1521- if (ED->isConstrainedExtension ())
1522- diagnoseAndRemoveAttr (attr,
1523- diag::attr_objc_implementation_must_be_unconditional);
1520+ if ( auto ED = dyn_cast <ExtensionDecl>(D)) {
1521+ if (ED->isConstrainedExtension ())
1522+ diagnoseAndRemoveAttr (attr,
1523+ diag::attr_objc_implementation_must_be_unconditional);
15241524
1525- auto CD = dyn_cast<ClassDecl>(ED->getExtendedNominal ());
1526- if (!CD) {
1527- diagnoseAndRemoveAttr (attr,
1528- diag::attr_objc_implementation_must_extend_class,
1529- ED->getExtendedNominal ());
1530- ED->getExtendedNominal ()->diagnose (diag::decl_declared_here,
1531- ED->getExtendedNominal ());
1532- return ;
1533- }
1525+ auto CD = dyn_cast<ClassDecl>(ED->getExtendedNominal ());
1526+ if (!CD) {
1527+ diagnoseAndRemoveAttr (attr,
1528+ diag::attr_objc_implementation_must_extend_class,
1529+ ED->getExtendedNominal ());
1530+ ED->getExtendedNominal ()->diagnose (diag::decl_declared_here,
1531+ ED->getExtendedNominal ());
1532+ return ;
1533+ }
15341534
1535- if (!CD->hasClangNode ()) {
1536- diagnoseAndRemoveAttr (attr, diag::attr_objc_implementation_must_be_imported,
1537- CD);
1538- CD->diagnose (diag::decl_declared_here, CD);
1539- return ;
1540- }
1535+ if (!CD->hasClangNode ()) {
1536+ diagnoseAndRemoveAttr (attr, diag::attr_objc_implementation_must_be_imported,
1537+ CD);
1538+ CD->diagnose (diag::decl_declared_here, CD);
1539+ return ;
1540+ }
15411541
1542- if (!CD->hasSuperclass ()) {
1543- diagnoseAndRemoveAttr (attr, diag::attr_objc_implementation_must_have_super,
1544- CD);
1545- CD->diagnose (diag::decl_declared_here, CD);
1546- return ;
1547- }
1542+ if (!CD->hasSuperclass ()) {
1543+ diagnoseAndRemoveAttr (attr, diag::attr_objc_implementation_must_have_super,
1544+ CD);
1545+ CD->diagnose (diag::decl_declared_here, CD);
1546+ return ;
1547+ }
15481548
1549- if (CD->isTypeErasedGenericClass ()) {
1550- diagnoseAndRemoveAttr (attr, diag::objc_implementation_cannot_have_generics,
1551- CD);
1552- CD->diagnose (diag::decl_declared_here, CD);
1553- }
1549+ if (CD->isTypeErasedGenericClass ()) {
1550+ diagnoseAndRemoveAttr (attr, diag::objc_implementation_cannot_have_generics,
1551+ CD);
1552+ CD->diagnose (diag::decl_declared_here, CD);
1553+ }
15541554
1555- if (!attr->isCategoryNameInvalid () && !ED->getImplementedObjCDecl ()) {
1556- diagnose (attr->getLocation (),
1557- diag::attr_objc_implementation_category_not_found,
1558- attr->CategoryName , CD);
1559-
1560- // attr->getRange() covers the attr name and argument list; adjust it to
1561- // exclude the first token.
1562- auto newStart = Lexer::getLocForEndOfToken (Ctx.SourceMgr ,
1563- attr->getRange ().Start );
1564- if (attr->getRange ().contains (newStart)) {
1565- auto argListRange = SourceRange (newStart, attr->getRange ().End );
1555+ if (!attr->isCategoryNameInvalid () && !ED->getImplementedObjCDecl ()) {
15661556 diagnose (attr->getLocation (),
1567- diag::attr_objc_implementation_fixit_remove_category_name)
1568- .fixItRemove (argListRange);
1557+ diag::attr_objc_implementation_category_not_found,
1558+ attr->CategoryName , CD);
1559+
1560+ // attr->getRange() covers the attr name and argument list; adjust it to
1561+ // exclude the first token.
1562+ auto newStart = Lexer::getLocForEndOfToken (Ctx.SourceMgr ,
1563+ attr->getRange ().Start );
1564+ if (attr->getRange ().contains (newStart)) {
1565+ auto argListRange = SourceRange (newStart, attr->getRange ().End );
1566+ diagnose (attr->getLocation (),
1567+ diag::attr_objc_implementation_fixit_remove_category_name)
1568+ .fixItRemove (argListRange);
1569+ }
1570+
1571+ attr->setCategoryNameInvalid ();
1572+
1573+ return ;
15691574 }
1575+ }
1576+ else if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
1577+ if (!attr->CategoryName .empty ()) {
1578+ auto diagnostic =
1579+ diagnose (attr->getLocation (),
1580+ diag::attr_objc_implementation_no_category_for_func, AFD);
15701581
1571- attr->setCategoryNameInvalid ();
1582+ // attr->getRange() covers the attr name and argument list; adjust it to
1583+ // exclude the first token.
1584+ auto newStart = Lexer::getLocForEndOfToken (Ctx.SourceMgr ,
1585+ attr->getRange ().Start );
1586+ if (attr->getRange ().contains (newStart)) {
1587+ auto argListRange = SourceRange (newStart, attr->getRange ().End );
1588+ diagnostic.fixItRemove (argListRange);
1589+ }
15721590
1573- return ;
1591+ attr->setCategoryNameInvalid ();
1592+ }
15741593 }
15751594}
15761595
0 commit comments