@@ -170,24 +170,32 @@ void ObjCReason::setAttrInvalid() const {
170
170
static void diagnoseTypeNotRepresentableInObjC (const DeclContext *DC,
171
171
Type T,
172
172
SourceRange TypeRange,
173
- DiagnosticBehavior behavior) {
173
+ DiagnosticBehavior behavior,
174
+ ObjCReason reason) {
174
175
auto &diags = DC->getASTContext ().Diags ;
176
+ auto language = reason.getForeignLanguage ();
175
177
176
178
// Special diagnostic for tuples.
177
179
if (T->is <TupleType>()) {
178
180
if (T->isVoid ())
179
- diags.diagnose (TypeRange.Start , diag::not_objc_empty_tuple)
181
+ diags.diagnose (TypeRange.Start , diag::not_objc_empty_tuple, language )
180
182
.highlight (TypeRange)
181
183
.limitBehavior (behavior);
182
184
else
183
- diags.diagnose (TypeRange.Start , diag::not_objc_tuple)
185
+ diags.diagnose (TypeRange.Start , diag::not_objc_tuple, language )
184
186
.highlight (TypeRange)
185
187
.limitBehavior (behavior);
186
188
return ;
187
189
}
188
190
189
191
// Special diagnostic for classes.
190
192
if (auto *CD = T->getClassOrBoundGenericClass ()) {
193
+ if (language == ForeignLanguage::C) {
194
+ diags.diagnose (TypeRange.Start , diag::cdecl_incompatible_with_classes)
195
+ .limitBehavior (behavior);
196
+ return ;
197
+ }
198
+
191
199
if (!CD->isObjC ())
192
200
diags.diagnose (TypeRange.Start , diag::not_objc_swift_class)
193
201
.highlight (TypeRange)
@@ -199,12 +207,14 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
199
207
if (auto *SD = T->getStructOrBoundGenericStruct ()) {
200
208
if (isa_and_nonnull<clang::CXXRecordDecl>(SD->getClangDecl ())) {
201
209
// This can be a non-trivial C++ record.
202
- diags.diagnose (TypeRange.Start , diag::not_objc_non_trivial_cxx_class)
210
+ diags.diagnose (TypeRange.Start , diag::not_objc_non_trivial_cxx_class,
211
+ language)
203
212
.highlight (TypeRange)
204
213
.limitBehavior (behavior);
205
214
return ;
206
215
}
207
- diags.diagnose (TypeRange.Start , diag::not_objc_swift_struct)
216
+ diags.diagnose (TypeRange.Start , diag::not_objc_swift_struct,
217
+ language)
208
218
.highlight (TypeRange)
209
219
.limitBehavior (behavior);
210
220
return ;
@@ -220,6 +230,13 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
220
230
221
231
// Special diagnostic for protocols and protocol compositions.
222
232
if (T->isExistentialType ()) {
233
+ // No protocol is representable in C.
234
+ if (language == ForeignLanguage::C) {
235
+ diags.diagnose (TypeRange.Start , diag::cdecl_incompatible_with_protocols)
236
+ .limitBehavior (behavior);
237
+ return ;
238
+ }
239
+
223
240
if (T->isAny ()) {
224
241
// Any is not @objc.
225
242
diags.diagnose (TypeRange.Start ,
@@ -267,28 +284,32 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
267
284
}
268
285
269
286
if (T->is <ArchetypeType>() || T->isTypeParameter ()) {
270
- diags.diagnose (TypeRange.Start , diag::not_objc_generic_type_param)
287
+ diags.diagnose (TypeRange.Start , diag::not_objc_generic_type_param,
288
+ language)
271
289
.highlight (TypeRange)
272
290
.limitBehavior (behavior);
273
291
return ;
274
292
}
275
293
276
294
if (auto fnTy = T->getAs <FunctionType>()) {
277
295
if (fnTy->getExtInfo ().isAsync ()) {
278
- diags.diagnose (TypeRange.Start , diag::not_objc_function_type_async)
296
+ diags.diagnose (TypeRange.Start , diag::not_objc_function_type_async,
297
+ language)
279
298
.highlight (TypeRange)
280
299
.limitBehavior (behavior);
281
300
return ;
282
301
}
283
302
284
303
if (fnTy->getExtInfo ().isThrowing ()) {
285
- diags.diagnose (TypeRange.Start , diag::not_objc_function_type_throwing)
304
+ diags.diagnose (TypeRange.Start , diag::not_objc_function_type_throwing,
305
+ language)
286
306
.highlight (TypeRange)
287
307
.limitBehavior (behavior);
288
308
return ;
289
309
}
290
310
291
- diags.diagnose (TypeRange.Start , diag::not_objc_function_type_param)
311
+ diags.diagnose (TypeRange.Start , diag::not_objc_function_type_param,
312
+ language)
292
313
.highlight (TypeRange)
293
314
.limitBehavior (behavior);
294
315
return ;
@@ -305,25 +326,26 @@ static void diagnoseFunctionParamNotRepresentable(
305
326
softenIfAccessNote (AFD, Reason.getAttr (),
306
327
AFD->diagnose (diag::objc_invalid_on_func_single_param_type,
307
328
AFD, getObjCDiagnosticAttrKind (Reason),
308
- ( unsigned ) language)
329
+ language)
309
330
.limitBehavior (behavior));
310
331
} else {
311
332
softenIfAccessNote (AFD, Reason.getAttr (),
312
333
AFD->diagnose (diag::objc_invalid_on_func_param_type,
313
334
AFD, ParamIndex + 1 , getObjCDiagnosticAttrKind (Reason),
314
- ( unsigned ) language)
335
+ language)
315
336
.limitBehavior (behavior));
316
337
}
317
338
SourceRange SR;
318
339
319
340
if (P->hasAttachedPropertyWrapper ()) {
320
341
auto wrapperTy = P->getPropertyWrapperBackingPropertyType ();
321
342
SR = P->getOutermostAttachedPropertyWrapper ()->getRange ();
322
- diagnoseTypeNotRepresentableInObjC (AFD, wrapperTy, SR, behavior);
343
+ diagnoseTypeNotRepresentableInObjC (AFD, wrapperTy, SR, behavior, Reason );
323
344
} else {
324
345
if (auto typeRepr = P->getTypeRepr ())
325
346
SR = typeRepr->getSourceRange ();
326
- diagnoseTypeNotRepresentableInObjC (AFD, P->getTypeInContext (), SR, behavior);
347
+ diagnoseTypeNotRepresentableInObjC (AFD, P->getTypeInContext (), SR,
348
+ behavior, Reason);
327
349
}
328
350
Reason.describe (AFD);
329
351
}
@@ -345,7 +367,7 @@ static bool isParamListRepresentableInLanguage(const AbstractFunctionDecl *AFD,
345
367
if (param->isVariadic ()) {
346
368
softenIfAccessNote (AFD, Reason.getAttr (),
347
369
diags.diagnose (param->getStartLoc (), diag::objc_invalid_on_func_variadic,
348
- getObjCDiagnosticAttrKind (Reason))
370
+ AFD, getObjCDiagnosticAttrKind (Reason))
349
371
.highlight (param->getSourceRange ())
350
372
.limitBehavior (behavior));
351
373
Reason.describe (AFD);
@@ -358,7 +380,7 @@ static bool isParamListRepresentableInLanguage(const AbstractFunctionDecl *AFD,
358
380
softenIfAccessNote (AFD, Reason.getAttr (),
359
381
diags.diagnose (param->getStartLoc (), diag::objc_invalid_on_func_inout,
360
382
AFD, getObjCDiagnosticAttrKind (Reason),
361
- ( unsigned ) language)
383
+ language)
362
384
.highlight (param->getSourceRange ())
363
385
.limitBehavior (behavior));
364
386
Reason.describe (AFD);
@@ -800,11 +822,11 @@ bool swift::isRepresentableInLanguage(
800
822
softenIfAccessNote (AFD, Reason.getAttr (),
801
823
AFD->diagnose (diag::objc_invalid_on_func_result_type,
802
824
FD, getObjCDiagnosticAttrKind (Reason),
803
- ( unsigned ) language)
825
+ language)
804
826
.limitBehavior (behavior));
805
827
diagnoseTypeNotRepresentableInObjC (FD, ResultType,
806
828
FD->getResultTypeSourceRange (),
807
- behavior);
829
+ behavior, Reason );
808
830
Reason.describe (FD);
809
831
return false ;
810
832
}
@@ -857,11 +879,11 @@ bool swift::isRepresentableInLanguage(
857
879
softenIfAccessNote (AFD, Reason.getAttr (),
858
880
AFD->diagnose (diag::objc_invalid_on_func_result_type,
859
881
FD, getObjCDiagnosticAttrKind (Reason),
860
- ( unsigned ) language)
882
+ language)
861
883
.limitBehavior (behavior));
862
884
diagnoseTypeNotRepresentableInObjC (FD, type,
863
885
FD->getResultTypeSourceRange (),
864
- behavior);
886
+ behavior, Reason );
865
887
Reason.describe (FD);
866
888
867
889
return true ;
@@ -1168,7 +1190,7 @@ bool swift::isRepresentableInObjC(const VarDecl *VD, ObjCReason Reason) {
1168
1190
.limitBehavior (behavior));
1169
1191
diagnoseTypeNotRepresentableInObjC (VD->getDeclContext (),
1170
1192
VD->getInterfaceType (),
1171
- TypeRange, behavior);
1193
+ TypeRange, behavior, Reason );
1172
1194
Reason.describe (VD);
1173
1195
}
1174
1196
@@ -1256,7 +1278,7 @@ bool swift::isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason) {
1256
1278
diagnoseTypeNotRepresentableInObjC (SD->getDeclContext (),
1257
1279
!IndexResult ? IndexType
1258
1280
: ElementType,
1259
- TypeRange, behavior);
1281
+ TypeRange, behavior, Reason );
1260
1282
Reason.describe (SD);
1261
1283
}
1262
1284
0 commit comments