@@ -170,24 +170,32 @@ void ObjCReason::setAttrInvalid() const {
170170static void diagnoseTypeNotRepresentableInObjC (const DeclContext *DC,
171171 Type T,
172172 SourceRange TypeRange,
173- DiagnosticBehavior behavior) {
173+ DiagnosticBehavior behavior,
174+ ObjCReason reason) {
174175 auto &diags = DC->getASTContext ().Diags ;
176+ auto language = reason.getForeignLanguage ();
175177
176178 // Special diagnostic for tuples.
177179 if (T->is <TupleType>()) {
178180 if (T->isVoid ())
179- diags.diagnose (TypeRange.Start , diag::not_objc_empty_tuple)
181+ diags.diagnose (TypeRange.Start , diag::not_objc_empty_tuple, language )
180182 .highlight (TypeRange)
181183 .limitBehavior (behavior);
182184 else
183- diags.diagnose (TypeRange.Start , diag::not_objc_tuple)
185+ diags.diagnose (TypeRange.Start , diag::not_objc_tuple, language )
184186 .highlight (TypeRange)
185187 .limitBehavior (behavior);
186188 return ;
187189 }
188190
189191 // Special diagnostic for classes.
190192 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+
191199 if (!CD->isObjC ())
192200 diags.diagnose (TypeRange.Start , diag::not_objc_swift_class)
193201 .highlight (TypeRange)
@@ -199,12 +207,14 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
199207 if (auto *SD = T->getStructOrBoundGenericStruct ()) {
200208 if (isa_and_nonnull<clang::CXXRecordDecl>(SD->getClangDecl ())) {
201209 // 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)
203212 .highlight (TypeRange)
204213 .limitBehavior (behavior);
205214 return ;
206215 }
207- diags.diagnose (TypeRange.Start , diag::not_objc_swift_struct)
216+ diags.diagnose (TypeRange.Start , diag::not_objc_swift_struct,
217+ language)
208218 .highlight (TypeRange)
209219 .limitBehavior (behavior);
210220 return ;
@@ -220,6 +230,13 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
220230
221231 // Special diagnostic for protocols and protocol compositions.
222232 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+
223240 if (T->isAny ()) {
224241 // Any is not @objc.
225242 diags.diagnose (TypeRange.Start ,
@@ -267,28 +284,32 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
267284 }
268285
269286 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)
271289 .highlight (TypeRange)
272290 .limitBehavior (behavior);
273291 return ;
274292 }
275293
276294 if (auto fnTy = T->getAs <FunctionType>()) {
277295 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)
279298 .highlight (TypeRange)
280299 .limitBehavior (behavior);
281300 return ;
282301 }
283302
284303 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)
286306 .highlight (TypeRange)
287307 .limitBehavior (behavior);
288308 return ;
289309 }
290310
291- diags.diagnose (TypeRange.Start , diag::not_objc_function_type_param)
311+ diags.diagnose (TypeRange.Start , diag::not_objc_function_type_param,
312+ language)
292313 .highlight (TypeRange)
293314 .limitBehavior (behavior);
294315 return ;
@@ -305,25 +326,26 @@ static void diagnoseFunctionParamNotRepresentable(
305326 softenIfAccessNote (AFD, Reason.getAttr (),
306327 AFD->diagnose (diag::objc_invalid_on_func_single_param_type,
307328 AFD, getObjCDiagnosticAttrKind (Reason),
308- ( unsigned ) language)
329+ language)
309330 .limitBehavior (behavior));
310331 } else {
311332 softenIfAccessNote (AFD, Reason.getAttr (),
312333 AFD->diagnose (diag::objc_invalid_on_func_param_type,
313334 AFD, ParamIndex + 1 , getObjCDiagnosticAttrKind (Reason),
314- ( unsigned ) language)
335+ language)
315336 .limitBehavior (behavior));
316337 }
317338 SourceRange SR;
318339
319340 if (P->hasAttachedPropertyWrapper ()) {
320341 auto wrapperTy = P->getPropertyWrapperBackingPropertyType ();
321342 SR = P->getOutermostAttachedPropertyWrapper ()->getRange ();
322- diagnoseTypeNotRepresentableInObjC (AFD, wrapperTy, SR, behavior);
343+ diagnoseTypeNotRepresentableInObjC (AFD, wrapperTy, SR, behavior, Reason );
323344 } else {
324345 if (auto typeRepr = P->getTypeRepr ())
325346 SR = typeRepr->getSourceRange ();
326- diagnoseTypeNotRepresentableInObjC (AFD, P->getTypeInContext (), SR, behavior);
347+ diagnoseTypeNotRepresentableInObjC (AFD, P->getTypeInContext (), SR,
348+ behavior, Reason);
327349 }
328350 Reason.describe (AFD);
329351}
@@ -345,7 +367,7 @@ static bool isParamListRepresentableInLanguage(const AbstractFunctionDecl *AFD,
345367 if (param->isVariadic ()) {
346368 softenIfAccessNote (AFD, Reason.getAttr (),
347369 diags.diagnose (param->getStartLoc (), diag::objc_invalid_on_func_variadic,
348- getObjCDiagnosticAttrKind (Reason))
370+ AFD, getObjCDiagnosticAttrKind (Reason))
349371 .highlight (param->getSourceRange ())
350372 .limitBehavior (behavior));
351373 Reason.describe (AFD);
@@ -358,7 +380,7 @@ static bool isParamListRepresentableInLanguage(const AbstractFunctionDecl *AFD,
358380 softenIfAccessNote (AFD, Reason.getAttr (),
359381 diags.diagnose (param->getStartLoc (), diag::objc_invalid_on_func_inout,
360382 AFD, getObjCDiagnosticAttrKind (Reason),
361- ( unsigned ) language)
383+ language)
362384 .highlight (param->getSourceRange ())
363385 .limitBehavior (behavior));
364386 Reason.describe (AFD);
@@ -800,11 +822,11 @@ bool swift::isRepresentableInLanguage(
800822 softenIfAccessNote (AFD, Reason.getAttr (),
801823 AFD->diagnose (diag::objc_invalid_on_func_result_type,
802824 FD, getObjCDiagnosticAttrKind (Reason),
803- ( unsigned ) language)
825+ language)
804826 .limitBehavior (behavior));
805827 diagnoseTypeNotRepresentableInObjC (FD, ResultType,
806828 FD->getResultTypeSourceRange (),
807- behavior);
829+ behavior, Reason );
808830 Reason.describe (FD);
809831 return false ;
810832 }
@@ -857,11 +879,11 @@ bool swift::isRepresentableInLanguage(
857879 softenIfAccessNote (AFD, Reason.getAttr (),
858880 AFD->diagnose (diag::objc_invalid_on_func_result_type,
859881 FD, getObjCDiagnosticAttrKind (Reason),
860- ( unsigned ) language)
882+ language)
861883 .limitBehavior (behavior));
862884 diagnoseTypeNotRepresentableInObjC (FD, type,
863885 FD->getResultTypeSourceRange (),
864- behavior);
886+ behavior, Reason );
865887 Reason.describe (FD);
866888
867889 return true ;
@@ -1168,7 +1190,7 @@ bool swift::isRepresentableInObjC(const VarDecl *VD, ObjCReason Reason) {
11681190 .limitBehavior (behavior));
11691191 diagnoseTypeNotRepresentableInObjC (VD->getDeclContext (),
11701192 VD->getInterfaceType (),
1171- TypeRange, behavior);
1193+ TypeRange, behavior, Reason );
11721194 Reason.describe (VD);
11731195 }
11741196
@@ -1256,7 +1278,7 @@ bool swift::isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason) {
12561278 diagnoseTypeNotRepresentableInObjC (SD->getDeclContext (),
12571279 !IndexResult ? IndexType
12581280 : ElementType,
1259- TypeRange, behavior);
1281+ TypeRange, behavior, Reason );
12601282 Reason.describe (SD);
12611283 }
12621284
0 commit comments