@@ -1141,6 +1141,13 @@ static Optional<ObjCReason> shouldMarkClassAsObjC(const ClassDecl *CD) {
1141
1141
auto ancestry = CD->checkAncestry ();
1142
1142
1143
1143
if (auto attr = CD->getAttrs ().getAttribute <ObjCAttr>()) {
1144
+ auto reason = objCReasonForObjCAttr (attr);
1145
+ auto behavior = behaviorLimitForObjCReason (reason, ctx);
1146
+
1147
+ SourceLoc attrLoc = attr->getLocation ();
1148
+ if (attrLoc.isInvalid ())
1149
+ attrLoc = CD->getLoc ();
1150
+
1144
1151
if (ancestry.contains (AncestryFlags::Generic)) {
1145
1152
if (attr->hasName () && !CD->isGenericContext ()) {
1146
1153
// @objc with a name on a non-generic subclass of a generic class is
@@ -1150,8 +1157,9 @@ static Optional<ObjCReason> shouldMarkClassAsObjC(const ClassDecl *CD) {
1150
1157
return None;
1151
1158
}
1152
1159
1153
- ctx.Diags .diagnose (attr->getLocation (), diag::objc_for_generic_class)
1154
- .fixItRemove (attr->getRangeWithAt ());
1160
+ ctx.Diags .diagnose (attrLoc, diag::objc_for_generic_class)
1161
+ .fixItRemove (attr->getRangeWithAt ())
1162
+ .limitBehavior (behavior);
1155
1163
}
1156
1164
1157
1165
// If the class has resilient ancestry, @objc just controls the runtime
@@ -1170,43 +1178,48 @@ static Optional<ObjCReason> shouldMarkClassAsObjC(const ClassDecl *CD) {
1170
1178
auto platform = prettyPlatformString (targetPlatform (ctx.LangOpts ));
1171
1179
auto range = getMinOSVersionForClassStubs (target);
1172
1180
auto *ancestor = getResilientAncestor (CD->getParentModule (), CD);
1173
- ctx.Diags .diagnose (attr-> getLocation () ,
1181
+ ctx.Diags .diagnose (attrLoc ,
1174
1182
diag::objc_for_resilient_class,
1175
1183
ancestor->getName (),
1176
1184
platform,
1177
1185
range.getLowerEndpoint ())
1178
- .fixItRemove (attr->getRangeWithAt ());
1186
+ .fixItRemove (attr->getRangeWithAt ())
1187
+ .limitBehavior (behavior);
1179
1188
}
1180
1189
1181
1190
// Only allow ObjC-rooted classes to be @objc.
1182
1191
// (Leave a hole for test cases.)
1183
1192
if (ancestry.contains (AncestryFlags::ObjC) &&
1184
1193
!ancestry.contains (AncestryFlags::ClangImported)) {
1185
1194
if (ctx.LangOpts .EnableObjCAttrRequiresFoundation ) {
1186
- ctx.Diags .diagnose (attr-> getLocation () ,
1195
+ ctx.Diags .diagnose (attrLoc ,
1187
1196
diag::invalid_objc_swift_rooted_class)
1188
- .fixItRemove (attr->getRangeWithAt ());
1197
+ .fixItRemove (attr->getRangeWithAt ())
1198
+ .limitBehavior (behavior);
1189
1199
// If the user has not spelled out a superclass, offer to insert
1190
1200
// 'NSObject'. We could also offer to replace the existing superclass,
1191
1201
// but that's a touch aggressive.
1192
1202
if (CD->getInherited ().empty ()) {
1193
1203
auto nameEndLoc = Lexer::getLocForEndOfToken (ctx.SourceMgr ,
1194
1204
CD->getNameLoc ());
1195
1205
CD->diagnose (diag::invalid_objc_swift_root_class_insert_nsobject)
1196
- .fixItInsert (nameEndLoc, " : NSObject" );
1206
+ .fixItInsert (nameEndLoc, " : NSObject" )
1207
+ .limitBehavior (behavior);
1197
1208
} else if (CD->getSuperclass ().isNull ()) {
1198
1209
CD->diagnose (diag::invalid_objc_swift_root_class_insert_nsobject)
1199
- .fixItInsert (CD->getInherited ().front ().getLoc (), " NSObject, " );
1210
+ .fixItInsert (CD->getInherited ().front ().getLoc (), " NSObject, " )
1211
+ .limitBehavior (behavior);
1200
1212
}
1201
1213
}
1202
1214
1203
1215
if (!ctx.LangOpts .EnableObjCInterop ) {
1204
- ctx.Diags .diagnose (attr->getLocation (), diag::objc_interop_disabled)
1205
- .fixItRemove (attr->getRangeWithAt ());
1216
+ ctx.Diags .diagnose (attrLoc, diag::objc_interop_disabled)
1217
+ .fixItRemove (attr->getRangeWithAt ())
1218
+ .limitBehavior (behavior);
1206
1219
}
1207
1220
}
1208
1221
1209
- return objCReasonForObjCAttr (CD-> getAttrs (). getAttribute <ObjCAttr>()) ;
1222
+ return reason ;
1210
1223
}
1211
1224
1212
1225
if (ancestry.contains (AncestryFlags::ObjC)) {
0 commit comments