2525#include " swift/SIL/SILModule.h"
2626#include " swift/SIL/SILType.h"
2727#include " clang/AST/ASTContext.h"
28+ #include " clang/AST/GlobalDecl.h"
2829#include " clang/AST/RecordLayout.h"
2930#include " clang/Basic/TargetInfo.h"
3031#include " clang/CodeGen/CodeGenABITypes.h"
@@ -430,7 +431,7 @@ namespace {
430431 bool forStaticCall = false ; // Used for objc_method (direct call or not).
431432
432433 // Indicates this is a c++ constructor call.
433- bool forCXXConstructorCall = false ;
434+ const clang::CXXConstructorDecl *cxxCtorDecl = nullptr ;
434435
435436 public:
436437 SmallVector<llvm::Type*, 8 > ParamIRTypes;
@@ -447,9 +448,9 @@ namespace {
447448
448449 SignatureExpansion (IRGenModule &IGM, CanSILFunctionType fnType,
449450 FunctionPointerKind fnKind, bool forStaticCall = false ,
450- bool forCXXConstructorCall = false )
451+ const clang::CXXConstructorDecl *cxxCtorDecl = nullptr )
451452 : IGM(IGM), FnType(fnType), forStaticCall(forStaticCall),
452- forCXXConstructorCall (forCXXConstructorCall ), FnKind(fnKind) {}
453+ cxxCtorDecl (cxxCtorDecl ), FnKind(fnKind) {}
453454
454455 // / Expand the components of the primary entrypoint of the function type.
455456 void expandFunctionType (
@@ -1374,12 +1375,8 @@ void SignatureExpansion::expandExternalSignatureTypes() {
13741375 IGM.getSILModule (), FnType, TypeExpansionContext::minimal ()));
13751376 }();
13761377
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);
13831380
13841381 // Now convert the parameters to Clang types.
13851382 auto params = FnType->getParameters ();
@@ -1415,7 +1412,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
14151412 }
14161413
14171414 case SILFunctionTypeRepresentation::CFunctionPointer:
1418- if (forCXXConstructorCall ) {
1415+ if (cxxCtorDecl ) {
14191416 auto clangTy = IGM.getClangASTContext ().getPointerType (
14201417 IGM.getClangType (SILResultTy));
14211418 paramTys.push_back (clangTy);
@@ -1447,10 +1444,15 @@ void SignatureExpansion::expandExternalSignatureTypes() {
14471444
14481445 // Generate function info for this signature.
14491446 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 ;
14541456
14551457 assert (FI.arg_size () == paramTys.size () &&
14561458 " Expected one ArgInfo for each parameter type!" );
@@ -1461,8 +1463,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
14611463 bool formalIndirectResult = FnType->getNumResults () > 0 &&
14621464 FnType->getSingleResult ().isFormalIndirect ();
14631465 assert (
1464- (forCXXConstructorCall || !formalIndirectResult ||
1465- returnInfo.isIndirect ()) &&
1466+ (cxxCtorDecl || !formalIndirectResult || returnInfo.isIndirect ()) &&
14661467 " swift and clang disagree on whether the result is returned indirectly" );
14671468#endif
14681469
@@ -2175,10 +2176,10 @@ Signature SignatureExpansion::getSignature() {
21752176Signature Signature::getUncached (IRGenModule &IGM,
21762177 CanSILFunctionType formalType,
21772178 FunctionPointerKind fpKind, bool forStaticCall,
2178- bool forCXXConstructorCall ) {
2179+ const clang::CXXConstructorDecl *cxxCtorDecl ) {
21792180 GenericContextScope scope (IGM, formalType->getInvocationGenericSignature ());
21802181 SignatureExpansion expansion (IGM, formalType, fpKind, forStaticCall,
2181- forCXXConstructorCall );
2182+ cxxCtorDecl );
21822183 expansion.expandFunctionType ();
21832184 return expansion.getSignature ();
21842185}
@@ -3995,6 +3996,12 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee,
39953996 // swiftcall function pointers through SIL as C functions anyway.
39963997 assert (FI.getExtParameterInfo (i).getABI () == clang::ParameterABI::Ordinary);
39973998
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+
39984005 // Add a padding argument if required.
39994006 if (auto *padType = AI.getPaddingType ())
40004007 out.add (llvm::UndefValue::get (padType));
@@ -4046,6 +4053,15 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee,
40464053 case clang::CodeGen::ABIArgInfo::IndirectAliased:
40474054 llvm_unreachable (" not implemented" );
40484055 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+
40494065 auto &ti = cast<LoadableTypeInfo>(IGF.getTypeInfo (paramType));
40504066
40514067 auto temp = ti.allocateStack (IGF, paramType, " indirect-temporary" );
0 commit comments