-
Notifications
You must be signed in to change notification settings - Fork 10.5k
C++ Interop: import call operators #36075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1757,6 +1757,13 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D, | |
|
||
case clang::DeclarationName::CXXOperatorName: { | ||
auto op = D->getDeclName().getCXXOverloadedOperator(); | ||
auto functionDecl = dyn_cast<clang::FunctionDecl>(D); | ||
if (!functionDecl) { | ||
// This can happen for example for templated operators functions. | ||
// We don't support those, yet. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this comment is still true. We can import templated operators. If you wanted to make a patch to support templated operators, that would also be super helpful. Probably a nfc. Additionally, I'm not sure we still need the check for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't really looked yet into how this behaves for templated operators. I'll try & if it works, I'll remove this comment in a separate PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even better. Thank you! |
||
return ImportedName(); | ||
} | ||
|
||
switch (op) { | ||
case clang::OverloadedOperatorKind::OO_Plus: | ||
case clang::OverloadedOperatorKind::OO_Minus: | ||
|
@@ -1775,21 +1782,20 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D, | |
case clang::OverloadedOperatorKind::OO_GreaterEqual: | ||
case clang::OverloadedOperatorKind::OO_AmpAmp: | ||
case clang::OverloadedOperatorKind::OO_PipePipe: | ||
if (auto FD = dyn_cast<clang::FunctionDecl>(D)) { | ||
baseName = clang::getOperatorSpelling(op); | ||
isFunction = true; | ||
argumentNames.resize( | ||
FD->param_size() + | ||
// C++ operators that are implemented as non-static member functions | ||
// get imported into Swift as static member functions that use an | ||
// additional parameter for the left-hand side operand instead of | ||
// the receiver object. | ||
(isa<clang::CXXMethodDecl>(D) ? 1 : 0)); | ||
} else { | ||
// This can happen for example for templated operators functions. | ||
// We don't support those, yet. | ||
return ImportedName(); | ||
} | ||
baseName = clang::getOperatorSpelling(op); | ||
isFunction = true; | ||
argumentNames.resize( | ||
functionDecl->param_size() + | ||
// C++ operators that are implemented as non-static member functions | ||
// get imported into Swift as static member functions that use an | ||
// additional parameter for the left-hand side operand instead of | ||
// the receiver object. | ||
(isa<clang::CXXMethodDecl>(D) ? 1 : 0)); | ||
break; | ||
case clang::OverloadedOperatorKind::OO_Call: | ||
baseName = "callAsFunction"; | ||
isFunction = true; | ||
addEmptyArgNamesForClangFunction(functionDecl, argumentNames); | ||
break; | ||
default: | ||
// We don't import these yet. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,13 +176,13 @@ AbstractionPattern | |
AbstractionPattern::getCurriedCXXMethod(CanType origType, | ||
const AbstractFunctionDecl *function) { | ||
auto clangMethod = cast<clang::CXXMethodDecl>(function->getClangDecl()); | ||
return getCurriedCXXMethod(origType, clangMethod); | ||
return getCurriedCXXMethod(origType, clangMethod, function->getImportAsMemberStatus()); | ||
} | ||
|
||
AbstractionPattern AbstractionPattern::getCurriedCXXOperatorMethod( | ||
CanType origType, const AbstractFunctionDecl *function) { | ||
auto clangMethod = cast<clang::CXXMethodDecl>(function->getClangDecl()); | ||
return getCurriedCXXOperatorMethod(origType, clangMethod); | ||
return getCurriedCXXOperatorMethod(origType, clangMethod, function->getImportAsMemberStatus()); | ||
} | ||
|
||
AbstractionPattern | ||
|
@@ -529,11 +529,12 @@ AbstractionPattern AbstractionPattern::getFunctionResultType() const { | |
getImportAsMemberStatus()); | ||
case Kind::CurriedCXXMethodType: | ||
return getPartialCurriedCXXMethod(getGenericSignatureForFunctionComponent(), | ||
getResultType(getType()), getCXXMethod()); | ||
getResultType(getType()), getCXXMethod(), | ||
getImportAsMemberStatus()); | ||
case Kind::CurriedCXXOperatorMethodType: | ||
return getPartialCurriedCXXOperatorMethod( | ||
getGenericSignatureForFunctionComponent(), getResultType(getType()), | ||
getCXXMethod()); | ||
getCXXMethod(), getImportAsMemberStatus()); | ||
case Kind::PartialCurriedObjCMethodType: | ||
case Kind::ObjCMethodType: { | ||
// If this is a foreign async function, the result type comes from the | ||
|
@@ -753,10 +754,19 @@ AbstractionPattern::getFunctionParamType(unsigned index) const { | |
auto params = cast<AnyFunctionType>(getType()).getParams(); | ||
auto paramType = params[index].getParameterType(); | ||
|
||
// The first parameter holds the left-hand-side operand, which gets passed | ||
// to the C++ function as the this pointer. | ||
if (index == 0) | ||
return getCXXMethodSelfPattern(paramType); | ||
// See importer::isImportedAsStatic | ||
bool isStatic = getImportAsMemberStatus().isStatic(); | ||
if (isStatic) { | ||
// The first parameter holds the left-hand-side operand, which gets passed | ||
// to the C++ function as the this pointer. | ||
if (index == 0) | ||
return getCXXMethodSelfPattern(paramType); | ||
} else { | ||
// The last parameter is 'self'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic might need to change once #34993 lands, but nothing you need to do. |
||
if (getKind() == Kind::CXXOperatorMethodType && | ||
index == params.size() - 1) | ||
return getCXXMethodSelfPattern(params.back().getParameterType()); | ||
} | ||
|
||
// A parameter of type () does not correspond to a Clang parameter. | ||
if (paramType->isVoid()) | ||
|
@@ -766,7 +776,7 @@ AbstractionPattern::getFunctionParamType(unsigned index) const { | |
auto methodType = getCXXMethod()->getType().getTypePtr(); | ||
return AbstractionPattern( | ||
getGenericSignatureForFunctionComponent(), paramType, | ||
getClangFunctionParameterType(methodType, index - 1)); | ||
getClangFunctionParameterType(methodType, index - (isStatic ? 1 : 0))); | ||
} | ||
case Kind::CurriedObjCMethodType: { | ||
auto params = cast<AnyFunctionType>(getType()).getParams(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it basically mimics the logic for
CFunctionAsMethodType
.