Skip to content

Commit 031ec43

Browse files
committed
Sema: Requestify most checks on @_cdecl
1 parent ce680ea commit 031ec43

File tree

4 files changed

+50
-17
lines changed

4 files changed

+50
-17
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4853,6 +4853,25 @@ class TypeCheckObjCImplementationRequest
48534853
bool isCached() const { return true; }
48544854
};
48554855

4856+
/// Check @cdecl-style attributes for compatibility with the foreign language.
4857+
class TypeCheckCDeclAttributeRequest
4858+
: public SimpleRequest<TypeCheckCDeclAttributeRequest,
4859+
evaluator::SideEffect(FuncDecl *FD,
4860+
CDeclAttr *attr),
4861+
RequestFlags::Cached> {
4862+
public:
4863+
using SimpleRequest::SimpleRequest;
4864+
4865+
private:
4866+
friend SimpleRequest;
4867+
4868+
evaluator::SideEffect
4869+
evaluate(Evaluator &evaluator, FuncDecl *FD, CDeclAttr *attr) const;
4870+
4871+
public:
4872+
bool isCached() const { return true; }
4873+
};
4874+
48564875
void simple_display(llvm::raw_ostream &out, ASTNode node);
48574876
void simple_display(llvm::raw_ostream &out, Type value);
48584877
void simple_display(llvm::raw_ostream &out, const TypeRepr *TyR);

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ SWIFT_REQUEST(TypeChecker, IsNonUserModuleRequest,
550550
SWIFT_REQUEST(TypeChecker, TypeCheckObjCImplementationRequest,
551551
unsigned(ExtensionDecl *),
552552
Cached, NoLocationInfo)
553+
SWIFT_REQUEST(TypeChecker, TypeCheckCDeclAttributeRequest,
554+
evaluator::SideEffect(FuncDecl *, CDeclAttr *),
555+
Cached, NoLocationInfo)
553556
SWIFT_REQUEST(TypeChecker, HasInitAccessorRequest,
554557
bool(AbstractStorageDecl *), Cached,
555558
NoLocationInfo)

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4143,3 +4143,28 @@ evaluate(Evaluator &evaluator, Decl *D) const {
41434143

41444144
return evaluator::SideEffect();
41454145
}
4146+
4147+
evaluator::SideEffect
4148+
TypeCheckCDeclAttributeRequest::evaluate(Evaluator &evaluator,
4149+
FuncDecl *FD,
4150+
CDeclAttr *attr) const {
4151+
auto &ctx = FD->getASTContext();
4152+
4153+
std::optional<ForeignAsyncConvention> asyncConvention;
4154+
std::optional<ForeignErrorConvention> errorConvention;
4155+
ObjCReason reason(ObjCReason::ExplicitlyCDecl, attr);
4156+
if (isRepresentableInObjC(FD, reason, asyncConvention, errorConvention)) {
4157+
if (FD->hasAsync()) {
4158+
FD->setForeignAsyncConvention(*asyncConvention);
4159+
ctx.Diags.diagnose(attr->getLocation(), diag::attr_decl_async,
4160+
attr, FD);
4161+
} else if (FD->hasThrows()) {
4162+
FD->setForeignErrorConvention(*errorConvention);
4163+
ctx.Diags.diagnose(attr->getLocation(), diag::cdecl_throws);
4164+
}
4165+
} else {
4166+
reason.setAttrInvalid();
4167+
}
4168+
4169+
return {};
4170+
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3781,24 +3781,10 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
37813781
}
37823782

37833783
// If the function is exported to C, it must be representable in (Obj-)C.
3784-
// FIXME: This needs to be moved to its own request if we want to
3785-
// productize @_cdecl.
37863784
if (auto CDeclAttr = FD->getAttrs().getAttribute<swift::CDeclAttr>()) {
3787-
std::optional<ForeignAsyncConvention> asyncConvention;
3788-
std::optional<ForeignErrorConvention> errorConvention;
3789-
ObjCReason reason(ObjCReason::ExplicitlyCDecl, CDeclAttr);
3790-
if (isRepresentableInObjC(FD, reason, asyncConvention, errorConvention)) {
3791-
if (FD->hasAsync()) {
3792-
FD->setForeignAsyncConvention(*asyncConvention);
3793-
Ctx.Diags.diagnose(CDeclAttr->getLocation(), diag::attr_decl_async,
3794-
CDeclAttr, FD);
3795-
} else if (FD->hasThrows()) {
3796-
FD->setForeignErrorConvention(*errorConvention);
3797-
Ctx.Diags.diagnose(CDeclAttr->getLocation(), diag::cdecl_throws);
3798-
}
3799-
} else {
3800-
reason.setAttrInvalid();
3801-
}
3785+
evaluateOrDefault(Ctx.evaluator,
3786+
TypeCheckCDeclAttributeRequest{FD, CDeclAttr},
3787+
{});
38023788
}
38033789

38043790
TypeChecker::checkObjCImplementation(FD);

0 commit comments

Comments
 (0)