@@ -48,6 +48,7 @@ swift::behaviorLimitForObjCReason(ObjCReason reason, ASTContext &ctx) {
48
48
LLVM_FALLTHROUGH;
49
49
50
50
case ObjCReason::ExplicitlyCDecl:
51
+ case ObjCReason::ExplicitlyUnderscoreCDecl:
51
52
case ObjCReason::ExplicitlyDynamic:
52
53
case ObjCReason::ExplicitlyObjC:
53
54
case ObjCReason::ExplicitlyObjCMembers:
@@ -81,6 +82,7 @@ swift::behaviorLimitForObjCReason(ObjCReason reason, ASTContext &ctx) {
81
82
unsigned swift::getObjCDiagnosticAttrKind (ObjCReason reason) {
82
83
switch (reason) {
83
84
case ObjCReason::ExplicitlyCDecl:
85
+ case ObjCReason::ExplicitlyUnderscoreCDecl:
84
86
case ObjCReason::ExplicitlyDynamic:
85
87
case ObjCReason::ExplicitlyObjC:
86
88
case ObjCReason::ExplicitlyObjCMembers:
@@ -132,6 +134,7 @@ void ObjCReason::describe(const Decl *D) const {
132
134
133
135
case ObjCReason::ExplicitlyObjCByAccessNote:
134
136
case ObjCReason::ExplicitlyCDecl:
137
+ case ObjCReason::ExplicitlyUnderscoreCDecl:
135
138
case ObjCReason::ExplicitlyDynamic:
136
139
case ObjCReason::ExplicitlyObjC:
137
140
case ObjCReason::ExplicitlyObjCMembers:
@@ -293,18 +296,21 @@ static void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
293
296
294
297
static void diagnoseFunctionParamNotRepresentable (
295
298
const AbstractFunctionDecl *AFD, unsigned NumParams,
296
- unsigned ParamIndex, const ParamDecl *P, ObjCReason Reason) {
299
+ unsigned ParamIndex, const ParamDecl *P, ObjCReason Reason,
300
+ ForeignLanguage Language) {
297
301
auto behavior = behaviorLimitForObjCReason (Reason, AFD->getASTContext ());
298
302
299
303
if (NumParams == 1 ) {
300
304
softenIfAccessNote (AFD, Reason.getAttr (),
301
305
AFD->diagnose (diag::objc_invalid_on_func_single_param_type,
302
- getObjCDiagnosticAttrKind (Reason))
306
+ AFD, getObjCDiagnosticAttrKind (Reason),
307
+ (unsigned )Language)
303
308
.limitBehavior (behavior));
304
309
} else {
305
310
softenIfAccessNote (AFD, Reason.getAttr (),
306
311
AFD->diagnose (diag::objc_invalid_on_func_param_type,
307
- ParamIndex + 1 , getObjCDiagnosticAttrKind (Reason))
312
+ AFD, ParamIndex + 1 , getObjCDiagnosticAttrKind (Reason),
313
+ (unsigned )Language)
308
314
.limitBehavior (behavior));
309
315
}
310
316
SourceRange SR;
@@ -321,9 +327,10 @@ static void diagnoseFunctionParamNotRepresentable(
321
327
Reason.describe (AFD);
322
328
}
323
329
324
- static bool isParamListRepresentableInObjC (const AbstractFunctionDecl *AFD,
325
- const ParameterList *PL,
326
- ObjCReason Reason) {
330
+ static bool isParamListRepresentableInLanguage (const AbstractFunctionDecl *AFD,
331
+ const ParameterList *PL,
332
+ ObjCReason Reason,
333
+ ForeignLanguage Language) {
327
334
// If you change this function, you must add or modify a test in PrintAsClang.
328
335
ASTContext &ctx = AFD->getASTContext ();
329
336
auto &diags = ctx.Diags ;
@@ -349,7 +356,7 @@ static bool isParamListRepresentableInObjC(const AbstractFunctionDecl *AFD,
349
356
if (param->isInOut ()) {
350
357
softenIfAccessNote (AFD, Reason.getAttr (),
351
358
diags.diagnose (param->getStartLoc (), diag::objc_invalid_on_func_inout,
352
- getObjCDiagnosticAttrKind (Reason))
359
+ AFD, getObjCDiagnosticAttrKind (Reason), ( unsigned )Language )
353
360
.highlight (param->getSourceRange ())
354
361
.limitBehavior (behavior));
355
362
Reason.describe (AFD);
@@ -362,11 +369,11 @@ static bool isParamListRepresentableInObjC(const AbstractFunctionDecl *AFD,
362
369
363
370
if (param->hasAttachedPropertyWrapper ()) {
364
371
if (param->getPropertyWrapperBackingPropertyType ()->isRepresentableIn (
365
- ForeignLanguage::ObjectiveC ,
372
+ Language ,
366
373
const_cast <AbstractFunctionDecl *>(AFD)))
367
374
continue ;
368
375
} else if (param->getTypeInContext ()->isRepresentableIn (
369
- ForeignLanguage::ObjectiveC ,
376
+ Language ,
370
377
const_cast <AbstractFunctionDecl *>(AFD))) {
371
378
continue ;
372
379
}
@@ -387,7 +394,7 @@ static bool isParamListRepresentableInObjC(const AbstractFunctionDecl *AFD,
387
394
388
395
IsObjC = false ;
389
396
diagnoseFunctionParamNotRepresentable (AFD, NumParams, ParamIndex,
390
- param, Reason);
397
+ param, Reason, Language );
391
398
}
392
399
return IsObjC;
393
400
}
@@ -645,14 +652,16 @@ static bool isValidObjectiveCErrorResultType(DeclContext *dc, Type type) {
645
652
llvm_unreachable (" Unhandled ForeignRepresentableKind in switch." );
646
653
}
647
654
648
- bool swift::isRepresentableInObjC (
655
+ bool swift::isRepresentableInLanguage (
649
656
const AbstractFunctionDecl *AFD, ObjCReason Reason,
650
657
std::optional<ForeignAsyncConvention> &asyncConvention,
651
- std::optional<ForeignErrorConvention> &errorConvention) {
658
+ std::optional<ForeignErrorConvention> &errorConvention,
659
+ ForeignLanguage Language) {
652
660
auto abiRole = ABIRoleInfo (AFD);
653
661
if (!abiRole.providesAPI () && abiRole.getCounterpart ())
654
- return isRepresentableInObjC (abiRole.getCounterpart (), Reason,
655
- asyncConvention, errorConvention);
662
+ return isRepresentableInLanguage (abiRole.getCounterpart (), Reason,
663
+ asyncConvention, errorConvention,
664
+ Language);
656
665
657
666
// Clear out the async and error conventions. They will be added later if
658
667
// needed.
@@ -688,6 +697,7 @@ bool swift::isRepresentableInObjC(
688
697
auto storage = accessor->getStorage ();
689
698
bool storageIsObjC = storage->isObjC ()
690
699
|| Reason == ObjCReason::ExplicitlyCDecl
700
+ || Reason == ObjCReason::ExplicitlyUnderscoreCDecl
691
701
|| Reason == ObjCReason::WitnessToObjC
692
702
|| Reason == ObjCReason::MemberOfObjCProtocol;
693
703
@@ -773,9 +783,10 @@ bool swift::isRepresentableInObjC(
773
783
isSpecialInit = init->isObjCZeroParameterWithLongSelector ();
774
784
775
785
if (!isSpecialInit &&
776
- !isParamListRepresentableInObjC (AFD,
777
- AFD->getParameters (),
778
- Reason)) {
786
+ !isParamListRepresentableInLanguage (AFD,
787
+ AFD->getParameters (),
788
+ Reason,
789
+ Language)) {
779
790
return false ;
780
791
}
781
792
@@ -785,11 +796,12 @@ bool swift::isRepresentableInObjC(
785
796
!ResultType->hasError () &&
786
797
!ResultType->isVoid () &&
787
798
!ResultType->isUninhabited () &&
788
- !ResultType->isRepresentableIn (ForeignLanguage::ObjectiveC ,
799
+ !ResultType->isRepresentableIn (Language ,
789
800
const_cast <FuncDecl *>(FD))) {
790
801
softenIfAccessNote (AFD, Reason.getAttr (),
791
802
AFD->diagnose (diag::objc_invalid_on_func_result_type,
792
- getObjCDiagnosticAttrKind (Reason))
803
+ FD, getObjCDiagnosticAttrKind (Reason),
804
+ (unsigned )Language)
793
805
.limitBehavior (behavior));
794
806
diagnoseTypeNotRepresentableInObjC (FD, ResultType,
795
807
FD->getResultTypeSourceRange (),
@@ -842,11 +854,11 @@ bool swift::isRepresentableInObjC(
842
854
completionHandlerParams.push_back (AnyFunctionType::Param (type));
843
855
844
856
// Make sure that the parameter type is representable in Objective-C.
845
- if (!type->isRepresentableIn (
846
- ForeignLanguage::ObjectiveC, const_cast <FuncDecl *>(FD))) {
857
+ if (!type->isRepresentableIn (Language, const_cast <FuncDecl *>(FD))) {
847
858
softenIfAccessNote (AFD, Reason.getAttr (),
848
859
AFD->diagnose (diag::objc_invalid_on_func_result_type,
849
- getObjCDiagnosticAttrKind (Reason))
860
+ FD, getObjCDiagnosticAttrKind (Reason),
861
+ (unsigned )Language)
850
862
.limitBehavior (behavior));
851
863
diagnoseTypeNotRepresentableInObjC (FD, type,
852
864
FD->getResultTypeSourceRange (),
@@ -1260,8 +1272,10 @@ bool swift::canBeRepresentedInObjC(const ValueDecl *decl) {
1260
1272
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
1261
1273
std::optional<ForeignAsyncConvention> asyncConvention;
1262
1274
std::optional<ForeignErrorConvention> errorConvention;
1263
- return isRepresentableInObjC (func, ObjCReason::MemberOfObjCMembersClass,
1264
- asyncConvention, errorConvention);
1275
+ return isRepresentableInLanguage (func,
1276
+ ObjCReason::MemberOfObjCMembersClass,
1277
+ asyncConvention, errorConvention,
1278
+ ForeignLanguage::ObjectiveC);
1265
1279
}
1266
1280
1267
1281
if (auto var = dyn_cast<VarDecl>(decl))
@@ -1865,8 +1879,9 @@ bool IsObjCRequest::evaluate(Evaluator &evaluator, ValueDecl *VD) const {
1865
1879
} else if (isa<DestructorDecl>(VD)) {
1866
1880
// Destructors need no additional checking.
1867
1881
} else if (auto func = dyn_cast<AbstractFunctionDecl>(VD)) {
1868
- if (!isRepresentableInObjC (
1869
- func, *isObjC, asyncConvention, errorConvention)) {
1882
+ if (!isRepresentableInLanguage (
1883
+ func, *isObjC, asyncConvention, errorConvention,
1884
+ ForeignLanguage::ObjectiveC)) {
1870
1885
isObjC->setAttrInvalid ();
1871
1886
return false ;
1872
1887
}
@@ -4150,17 +4165,25 @@ TypeCheckCDeclAttributeRequest::evaluate(Evaluator &evaluator,
4150
4165
CDeclAttr *attr) const {
4151
4166
auto &ctx = FD->getASTContext ();
4152
4167
4168
+ auto lang = FD->getCDeclKind ();
4169
+ assert (lang && " missing @cdecl?" );
4170
+ auto kind = lang == ForeignLanguage::ObjectiveC
4171
+ ? ObjCReason::ExplicitlyUnderscoreCDecl
4172
+ : ObjCReason::ExplicitlyCDecl;
4173
+ ObjCReason reason (kind, attr);
4174
+
4153
4175
std::optional<ForeignAsyncConvention> asyncConvention;
4154
4176
std::optional<ForeignErrorConvention> errorConvention;
4155
- ObjCReason reason (ObjCReason::ExplicitlyCDecl, attr);
4156
- if ( isRepresentableInObjC (FD, reason, asyncConvention, errorConvention )) {
4177
+ if ( isRepresentableInLanguage (FD, reason, asyncConvention, errorConvention,
4178
+ *lang )) {
4157
4179
if (FD->hasAsync ()) {
4158
4180
FD->setForeignAsyncConvention (*asyncConvention);
4159
4181
ctx.Diags .diagnose (attr->getLocation (), diag::attr_decl_async,
4160
4182
attr, FD);
4161
4183
} else if (FD->hasThrows ()) {
4162
4184
FD->setForeignErrorConvention (*errorConvention);
4163
- ctx.Diags .diagnose (attr->getLocation (), diag::cdecl_throws);
4185
+ ctx.Diags .diagnose (attr->getLocation (), diag::cdecl_throws,
4186
+ attr);
4164
4187
}
4165
4188
} else {
4166
4189
reason.setAttrInvalid ();
0 commit comments