25
25
#include " swift/SIL/SILModule.h"
26
26
#include " swift/SIL/SILType.h"
27
27
#include " clang/AST/ASTContext.h"
28
+ #include " clang/AST/GlobalDecl.h"
28
29
#include " clang/AST/RecordLayout.h"
29
30
#include " clang/Basic/TargetInfo.h"
30
31
#include " clang/CodeGen/CodeGenABITypes.h"
@@ -430,7 +431,7 @@ namespace {
430
431
bool forStaticCall = false ; // Used for objc_method (direct call or not).
431
432
432
433
// Indicates this is a c++ constructor call.
433
- bool forCXXConstructorCall = false ;
434
+ const clang::CXXConstructorDecl *cxxCtorDecl = nullptr ;
434
435
435
436
public:
436
437
SmallVector<llvm::Type*, 8 > ParamIRTypes;
@@ -447,9 +448,9 @@ namespace {
447
448
448
449
SignatureExpansion (IRGenModule &IGM, CanSILFunctionType fnType,
449
450
FunctionPointerKind fnKind, bool forStaticCall = false ,
450
- bool forCXXConstructorCall = false )
451
+ const clang::CXXConstructorDecl *cxxCtorDecl = nullptr )
451
452
: IGM(IGM), FnType(fnType), forStaticCall(forStaticCall),
452
- forCXXConstructorCall (forCXXConstructorCall ), FnKind(fnKind) {}
453
+ cxxCtorDecl (cxxCtorDecl ), FnKind(fnKind) {}
453
454
454
455
// / Expand the components of the primary entrypoint of the function type.
455
456
void expandFunctionType (
@@ -1374,12 +1375,8 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1374
1375
IGM.getSILModule (), FnType, TypeExpansionContext::minimal ()));
1375
1376
}();
1376
1377
1377
- // Convert the SIL result type to a Clang type. If this is for a c++
1378
- // constructor, use 'void' as the return type.
1379
- auto clangResultTy = IGM.getClangType (
1380
- forCXXConstructorCall
1381
- ? SILType::getPrimitiveObjectType (IGM.Context .TheEmptyTupleType )
1382
- : SILResultTy);
1378
+ // Convert the SIL result type to a Clang type.
1379
+ auto clangResultTy = IGM.getClangType (SILResultTy);
1383
1380
1384
1381
// Now convert the parameters to Clang types.
1385
1382
auto params = FnType->getParameters ();
@@ -1415,7 +1412,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1415
1412
}
1416
1413
1417
1414
case SILFunctionTypeRepresentation::CFunctionPointer:
1418
- if (forCXXConstructorCall ) {
1415
+ if (cxxCtorDecl ) {
1419
1416
auto clangTy = IGM.getClangASTContext ().getPointerType (
1420
1417
IGM.getClangType (SILResultTy));
1421
1418
paramTys.push_back (clangTy);
@@ -1447,10 +1444,15 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1447
1444
1448
1445
// Generate function info for this signature.
1449
1446
auto extInfo = clang::FunctionType::ExtInfo ();
1450
- auto &FI = clang::CodeGen::arrangeFreeFunctionCall (IGM.ClangCodeGen ->CGM (),
1451
- clangResultTy, paramTys, extInfo,
1452
- clang::CodeGen::RequiredArgs::All);
1453
- ForeignInfo.ClangInfo = &FI;
1447
+
1448
+ if (cxxCtorDecl)
1449
+ ForeignInfo.ClangInfo = &clang::CodeGen::arrangeCXXStructorDeclaration (
1450
+ IGM.ClangCodeGen ->CGM (), {cxxCtorDecl, clang::Ctor_Complete});
1451
+ else
1452
+ ForeignInfo.ClangInfo = &clang::CodeGen::arrangeFreeFunctionCall (
1453
+ IGM.ClangCodeGen ->CGM (), clangResultTy, paramTys, extInfo,
1454
+ clang::CodeGen::RequiredArgs::All);
1455
+ auto &FI = *ForeignInfo.ClangInfo ;
1454
1456
1455
1457
assert (FI.arg_size () == paramTys.size () &&
1456
1458
" Expected one ArgInfo for each parameter type!" );
@@ -1461,8 +1463,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1461
1463
bool formalIndirectResult = FnType->getNumResults () > 0 &&
1462
1464
FnType->getSingleResult ().isFormalIndirect ();
1463
1465
assert (
1464
- (forCXXConstructorCall || !formalIndirectResult ||
1465
- returnInfo.isIndirect ()) &&
1466
+ (cxxCtorDecl || !formalIndirectResult || returnInfo.isIndirect ()) &&
1466
1467
" swift and clang disagree on whether the result is returned indirectly" );
1467
1468
#endif
1468
1469
@@ -2175,10 +2176,10 @@ Signature SignatureExpansion::getSignature() {
2175
2176
Signature Signature::getUncached (IRGenModule &IGM,
2176
2177
CanSILFunctionType formalType,
2177
2178
FunctionPointerKind fpKind, bool forStaticCall,
2178
- bool forCXXConstructorCall ) {
2179
+ const clang::CXXConstructorDecl *cxxCtorDecl ) {
2179
2180
GenericContextScope scope (IGM, formalType->getInvocationGenericSignature ());
2180
2181
SignatureExpansion expansion (IGM, formalType, fpKind, forStaticCall,
2181
- forCXXConstructorCall );
2182
+ cxxCtorDecl );
2182
2183
expansion.expandFunctionType ();
2183
2184
return expansion.getSignature ();
2184
2185
}
@@ -3995,6 +3996,12 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee,
3995
3996
// swiftcall function pointers through SIL as C functions anyway.
3996
3997
assert (FI.getExtParameterInfo (i).getABI () == clang::ParameterABI::Ordinary);
3997
3998
3999
+ assert ((!silConv.isSILIndirect (params[i - firstParam]) ||
4000
+ AI.getKind () == clang::CodeGen::ABIArgInfo::Direct ||
4001
+ AI.getKind () == clang::CodeGen::ABIArgInfo::Indirect) &&
4002
+ " indirect SIL types passed indirectly should be classified as "
4003
+ " either Direct or Indirect" );
4004
+
3998
4005
// Add a padding argument if required.
3999
4006
if (auto *padType = AI.getPaddingType ())
4000
4007
out.add (llvm::UndefValue::get (padType));
@@ -4046,6 +4053,15 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee,
4046
4053
case clang::CodeGen::ABIArgInfo::IndirectAliased:
4047
4054
llvm_unreachable (" not implemented" );
4048
4055
case clang::CodeGen::ABIArgInfo::Indirect: {
4056
+ // If this is a SIL type passed indirectly, avoid emitting a redundant
4057
+ // initializing copy.
4058
+ if (silConv.isSILIndirect (params[i - firstParam])) {
4059
+ assert (paramType.isAddress () && " SIL type is not an address?" );
4060
+ auto addr = in.claimNext ();
4061
+ out.add (addr);
4062
+ break ;
4063
+ }
4064
+
4049
4065
auto &ti = cast<LoadableTypeInfo>(IGF.getTypeInfo (paramType));
4050
4066
4051
4067
auto temp = ti.allocateStack (IGF, paramType, " indirect-temporary" );
0 commit comments