Skip to content

Commit 53ab3ef

Browse files
authored
Merge pull request #34993 from zoecarver/cxx/cxxmethod-representation
[cxx-interop] Add SIL function representation cxx_method; Support extending C++ types.
2 parents bebe119 + 036361d commit 53ab3ef

37 files changed

+370
-102
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,8 @@ Types
591591
FUNCTION-KIND ::= 'B' // objc block function type
592592
FUNCTION-KIND ::= 'zB' C-TYPE // objc block type with non-canonical C type
593593
FUNCTION-KIND ::= 'L' // objc block function type with canonical C type (escaping) (DWARF only; otherwise use 'B' or 'zB' C-TYPE)
594-
FUNCTION-KIND ::= 'C' // C function pointer type
595-
FUNCTION-KIND ::= 'zC' C-TYPE // C function pointer type with with non-canonical C type
594+
FUNCTION-KIND ::= 'C' // C function pointer / C++ method type
595+
FUNCTION-KIND ::= 'zC' C-TYPE // C function pointer / C++ method type with with non-canonical C type
596596
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
597597
FUNCTION-KIND ::= 'E' // function type (noescape)
598598

include/swift/AST/ExtInfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ enum class SILFunctionTypeRepresentation : uint8_t {
167167

168168
/// A closure invocation function that has not been bound to a context.
169169
Closure,
170+
171+
/// A C++ method that takes a "this" argument (not a static C++ method or
172+
/// constructor). Except for
173+
/// handling the "this" argument, has the same behavior as "CFunctionPointer".
174+
CXXMethod,
170175
};
171176

172177
/// Returns true if the function with this convention doesn't carry a context.
@@ -196,6 +201,7 @@ isThinRepresentation(SILFunctionTypeRepresentation rep) {
196201
case SILFunctionTypeRepresentation::WitnessMethod:
197202
case SILFunctionTypeRepresentation::CFunctionPointer:
198203
case SILFunctionTypeRepresentation::Closure:
204+
case SILFunctionTypeRepresentation::CXXMethod:
199205
return true;
200206
}
201207
llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch.");
@@ -232,6 +238,7 @@ convertRepresentation(SILFunctionTypeRepresentation rep) {
232238
return {FunctionTypeRepresentation::Block};
233239
case SILFunctionTypeRepresentation::Thin:
234240
return {FunctionTypeRepresentation::Thin};
241+
case SILFunctionTypeRepresentation::CXXMethod:
235242
case SILFunctionTypeRepresentation::CFunctionPointer:
236243
return {FunctionTypeRepresentation::CFunctionPointer};
237244
case SILFunctionTypeRepresentation::Method:
@@ -252,6 +259,7 @@ constexpr bool canBeCalledIndirectly(SILFunctionTypeRepresentation rep) {
252259
case SILFunctionTypeRepresentation::CFunctionPointer:
253260
case SILFunctionTypeRepresentation::Block:
254261
case SILFunctionTypeRepresentation::Closure:
262+
case SILFunctionTypeRepresentation::CXXMethod:
255263
return false;
256264
case SILFunctionTypeRepresentation::ObjCMethod:
257265
case SILFunctionTypeRepresentation::Method:
@@ -269,6 +277,7 @@ template <typename Repr> constexpr bool shouldStoreClangType(Repr repr) {
269277
switch (static_cast<SILFunctionTypeRepresentation>(repr)) {
270278
case SILFunctionTypeRepresentation::CFunctionPointer:
271279
case SILFunctionTypeRepresentation::Block:
280+
case SILFunctionTypeRepresentation::CXXMethod:
272281
return true;
273282
case SILFunctionTypeRepresentation::ObjCMethod:
274283
case SILFunctionTypeRepresentation::Thick:
@@ -392,6 +401,7 @@ class ASTExtInfoBuilder {
392401
case SILFunctionTypeRepresentation::ObjCMethod:
393402
case SILFunctionTypeRepresentation::Method:
394403
case SILFunctionTypeRepresentation::WitnessMethod:
404+
case SILFunctionTypeRepresentation::CXXMethod:
395405
return true;
396406
}
397407
llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch.");
@@ -618,6 +628,7 @@ SILFunctionLanguage getSILFunctionLanguage(SILFunctionTypeRepresentation rep) {
618628
case SILFunctionTypeRepresentation::ObjCMethod:
619629
case SILFunctionTypeRepresentation::CFunctionPointer:
620630
case SILFunctionTypeRepresentation::Block:
631+
case SILFunctionTypeRepresentation::CXXMethod:
621632
return SILFunctionLanguage::C;
622633
case SILFunctionTypeRepresentation::Thick:
623634
case SILFunctionTypeRepresentation::Thin:
@@ -750,6 +761,7 @@ class SILExtInfoBuilder {
750761
case Representation::ObjCMethod:
751762
case Representation::Method:
752763
case Representation::WitnessMethod:
764+
case SILFunctionTypeRepresentation::CXXMethod:
753765
return true;
754766
}
755767
llvm_unreachable("Unhandled Representation in switch.");
@@ -767,6 +779,7 @@ class SILExtInfoBuilder {
767779
case Representation::Method:
768780
case Representation::WitnessMethod:
769781
case Representation::Closure:
782+
case SILFunctionTypeRepresentation::CXXMethod:
770783
return false;
771784
}
772785
llvm_unreachable("Unhandled Representation in switch.");

include/swift/SIL/ApplySite.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ class ApplySite {
237237
bool isCalleeThin() const {
238238
switch (getSubstCalleeType()->getRepresentation()) {
239239
case SILFunctionTypeRepresentation::CFunctionPointer:
240+
case SILFunctionTypeRepresentation::CXXMethod:
240241
case SILFunctionTypeRepresentation::Thin:
241242
case SILFunctionTypeRepresentation::Method:
242243
case SILFunctionTypeRepresentation::ObjCMethod:

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ getSILFunctionTypeRepresentationString(SILFunctionType::Representation value) {
129129
case SILFunctionType::Representation::Thick: return "thick";
130130
case SILFunctionType::Representation::Block: return "block";
131131
case SILFunctionType::Representation::CFunctionPointer: return "c";
132+
case SILFunctionType::Representation::CXXMethod:
133+
return "cxx_method";
132134
case SILFunctionType::Representation::Thin: return "thin";
133135
case SILFunctionType::Representation::Method: return "method";
134136
case SILFunctionType::Representation::ObjCMethod: return "objc_method";

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
18451845
OpArgs.push_back('B');
18461846
appendClangTypeToVec(OpArgs);
18471847
break;
1848+
case SILFunctionTypeRepresentation::CXXMethod:
18481849
case SILFunctionTypeRepresentation::CFunctionPointer:
18491850
if (!mangleClangType) {
18501851
OpArgs.push_back('C');

lib/AST/ASTPrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4886,6 +4886,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
48864886
case SILFunctionType::Representation::Method:
48874887
Printer << "method";
48884888
break;
4889+
case SILFunctionType::Representation::CXXMethod:
4890+
Printer << "cxx_method";
4891+
break;
48894892
case SILFunctionType::Representation::ObjCMethod:
48904893
Printer << "objc_method";
48914894
break;
@@ -4964,6 +4967,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
49644967
case SILFunctionType::Representation::Method:
49654968
Printer << "method";
49664969
break;
4970+
case SILFunctionType::Representation::CXXMethod:
4971+
Printer << "cxx_method";
4972+
break;
49674973
case SILFunctionType::Representation::ObjCMethod:
49684974
Printer << "objc_method";
49694975
break;

lib/AST/ClangTypeConverter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ const clang::Type *ClangTypeConverter::getFunctionType(
212212
return nullptr;
213213

214214
switch (repr) {
215+
case SILFunctionType::Representation::CXXMethod:
215216
case SILFunctionType::Representation::CFunctionPointer:
216217
return ClangASTContext.getPointerType(fn).getTypePtr();
217218
case SILFunctionType::Representation::Block:

lib/AST/ExtInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Optional<UnexpectedClangTypeError> UnexpectedClangTypeError::checkClangType(
6868
#else
6969
bool isBlock = true;
7070
switch (silRep) {
71+
case SILFunctionTypeRepresentation::CXXMethod:
7172
case SILFunctionTypeRepresentation::CFunctionPointer:
7273
isBlock = false;
7374
LLVM_FALLTHROUGH;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,18 +4085,20 @@ namespace {
40854085
templateParams);
40864086

40874087
if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
4088+
// Subscripts and call operators are imported as normal methods.
4089+
bool staticOperator = mdecl->isOverloadedOperator() &&
4090+
mdecl->getOverloadedOperator() != clang::OO_Call &&
4091+
mdecl->getOverloadedOperator() != clang::OO_Subscript;
40884092
if (mdecl->isStatic() ||
40894093
// C++ operators that are implemented as non-static member
40904094
// functions get imported into Swift as static member functions
40914095
// that use an additional parameter for the left-hand side operand
40924096
// instead of the receiver object.
4093-
(mdecl->getDeclName().getNameKind() ==
4094-
clang::DeclarationName::CXXOperatorName &&
4095-
isImportedAsStatic(mdecl->getOverloadedOperator()))) {
4097+
staticOperator) {
40964098
selfIdx = None;
40974099
} else {
4098-
selfIdx = 0;
4099-
// Don't import members of a class decl as mutating.
4100+
// Swift imports the "self" param last, even for clang functions.
4101+
selfIdx = bodyParams ? bodyParams->size() : 0;
41004102
// If the method is imported as mutating, this implicitly makes the
41014103
// parameter indirect.
41024104
selfIsInOut =

lib/ClangImporter/ImportType.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1897,7 +1897,11 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
18971897
// imported into Swift as static methods that have an additional
18981898
// parameter for the left-hand side operand instead of the receiver object.
18991899
if (auto CMD = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
1900-
if (clangDecl->isOverloadedOperator() && isImportedAsStatic(clangDecl->getOverloadedOperator())) {
1900+
// Subscripts and call operators are imported as normal methods.
1901+
bool staticOperator = clangDecl->isOverloadedOperator() &&
1902+
clangDecl->getOverloadedOperator() != clang::OO_Call &&
1903+
clangDecl->getOverloadedOperator() != clang::OO_Subscript;
1904+
if (staticOperator) {
19011905
auto param = new (SwiftContext)
19021906
ParamDecl(SourceLoc(), SourceLoc(), Identifier(), SourceLoc(),
19031907
SwiftContext.getIdentifier("lhs"), dc);

0 commit comments

Comments
 (0)