Skip to content

Commit 9ddee0f

Browse files
committed
Call arrangeCXXStructorDeclaration to arrange constructor signatures
1 parent 6a83363 commit 9ddee0f

File tree

6 files changed

+67
-47
lines changed

6 files changed

+67
-47
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
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() {
21752176
Signature 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");

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3583,8 +3583,7 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
35833583
}
35843584

35853585
if (cxxCtor) {
3586-
Signature signature = getSignature(f->getLoweredFunctionType(),
3587-
/*isCXXConstructorCall*/ true);
3586+
Signature signature = getSignature(f->getLoweredFunctionType(), cxxCtor);
35883587

35893588
// The thunk has private linkage, so it doesn't need to have a predictable
35903589
// mangled name -- we just need to make sure the name is unique.

lib/IRGen/GenFunc.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ namespace {
131131
FuncSignatureInfo(CanSILFunctionType formalType)
132132
: FormalType(formalType) {}
133133

134-
Signature getCXXConstructorSignature(IRGenModule &IGM) const;
134+
Signature
135+
getCXXConstructorSignature(const clang::CXXConstructorDecl *cxxCtorDecl,
136+
IRGenModule &IGM) const;
135137
Signature getSignature(IRGenModule &IGM) const;
136138
};
137139

@@ -676,17 +678,16 @@ Signature FuncSignatureInfo::getSignature(IRGenModule &IGM) const {
676678
return TheSignature;
677679
}
678680

679-
Signature
680-
FuncSignatureInfo::getCXXConstructorSignature(IRGenModule &IGM) const {
681+
Signature FuncSignatureInfo::getCXXConstructorSignature(
682+
const clang::CXXConstructorDecl *cxxCtorDecl, IRGenModule &IGM) const {
681683
// If it's already been filled in, we're done.
682684
if (TheCXXConstructorSignature.isValid())
683685
return TheCXXConstructorSignature;
684686

685687
// Update the cache and return.
686688
TheCXXConstructorSignature =
687689
Signature::getUncached(IGM, FormalType, FunctionPointerKind(FormalType),
688-
/*forStaticCall*/ false,
689-
/*forCXXConstructorCall*/ true);
690+
/*forStaticCall*/ false, cxxCtorDecl);
690691
assert(TheCXXConstructorSignature.isValid());
691692
return TheCXXConstructorSignature;
692693
}
@@ -729,16 +730,17 @@ getFuncSignatureInfoForLowered(IRGenModule &IGM, CanSILFunctionType type) {
729730
llvm_unreachable("bad function type representation");
730731
}
731732

732-
Signature IRGenModule::getSignature(CanSILFunctionType type,
733-
bool isCXXConstructorCall) {
733+
Signature
734+
IRGenModule::getSignature(CanSILFunctionType type,
735+
const clang::CXXConstructorDecl *cxxCtorDecl) {
734736
return getSignature(type, FunctionPointerKind(type), /*forStaticCall*/ false,
735-
isCXXConstructorCall);
737+
cxxCtorDecl);
736738
}
737739

738-
Signature IRGenModule::getSignature(CanSILFunctionType type,
739-
FunctionPointerKind kind,
740-
bool forStaticCall,
741-
bool isCXXConstructorCall) {
740+
Signature
741+
IRGenModule::getSignature(CanSILFunctionType type, FunctionPointerKind kind,
742+
bool forStaticCall,
743+
const clang::CXXConstructorDecl *cxxCtorDecl) {
742744
// Don't bother caching if we're working with a special kind.
743745
if (kind.isSpecial())
744746
return Signature::getUncached(*this, type, kind);
@@ -751,8 +753,8 @@ Signature IRGenModule::getSignature(CanSILFunctionType type,
751753
return objcSigInfo.getDirectSignature(*this);
752754
}
753755

754-
if (isCXXConstructorCall)
755-
return sigInfo.getCXXConstructorSignature(*this);
756+
if (cxxCtorDecl)
757+
return sigInfo.getCXXConstructorSignature(cxxCtorDecl, *this);
756758

757759
return sigInfo.getSignature(*this);
758760
}

lib/IRGen/IRGenModule.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,11 +1574,13 @@ private: \
15741574
void finalizeClangCodeGen();
15751575
void finishEmitAfterTopLevel();
15761576

1577-
Signature getSignature(CanSILFunctionType fnType,
1578-
bool isCXXConstructorCall = false);
1579-
Signature getSignature(CanSILFunctionType fnType, FunctionPointerKind kind,
1580-
bool forStaticCall = false,
1581-
bool isCXXConstructorCall = false);
1577+
Signature
1578+
getSignature(CanSILFunctionType fnType,
1579+
const clang::CXXConstructorDecl *cxxCtorDecl = nullptr);
1580+
Signature
1581+
getSignature(CanSILFunctionType fnType, FunctionPointerKind kind,
1582+
bool forStaticCall = false,
1583+
const clang::CXXConstructorDecl *cxxCtorDecl = nullptr);
15821584
llvm::FunctionType *getFunctionType(CanSILFunctionType type,
15831585
llvm::AttributeList &attrs,
15841586
ForeignFunctionInfo *foreignInfo=nullptr);

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2969,13 +2969,13 @@ void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
29692969
auto fnType = fn->getLoweredFunctionType();
29702970

29712971
auto fpKind = irgen::classifyFunctionPointerKind(fn);
2972-
bool isCXXConstructor = false;
2972+
const clang::CXXConstructorDecl *cxxCtorDecl = nullptr;
29732973

29742974
if (auto *clangFnDecl = fn->getClangDecl())
2975-
isCXXConstructor = isa<clang::CXXConstructorDecl>(clangFnDecl);
2975+
cxxCtorDecl = dyn_cast<clang::CXXConstructorDecl>(clangFnDecl);
29762976

2977-
auto sig = IGM.getSignature(fnType, fpKind, true /*forStaticCall*/,
2978-
isCXXConstructor);
2977+
auto sig =
2978+
IGM.getSignature(fnType, fpKind, true /*forStaticCall*/, cxxCtorDecl);
29792979

29802980
// Note that the pointer value returned by getAddrOfSILFunction doesn't
29812981
// necessarily have element type sig.getType(), e.g. if it's imported.

lib/IRGen/Signature.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace llvm {
3131
}
3232

3333
namespace clang {
34+
class CXXConstructorDecl;
3435
namespace CodeGen {
3536
class CGFunctionInfo;
3637
}
@@ -202,10 +203,10 @@ class Signature {
202203
/// This is a private detail of the implementation of
203204
/// IRGenModule::getSignature(CanSILFunctionType), which is what
204205
/// clients should generally be using.
205-
static Signature getUncached(IRGenModule &IGM, CanSILFunctionType formalType,
206-
FunctionPointerKind kind,
207-
bool forStaticCall = false,
208-
bool forCXXConstructorCall = false);
206+
static Signature
207+
getUncached(IRGenModule &IGM, CanSILFunctionType formalType,
208+
FunctionPointerKind kind, bool forStaticCall = false,
209+
const clang::CXXConstructorDecl *cxxCtorDecl = nullptr);
209210

210211
static SignatureExpansionABIDetails
211212
getUncachedABIDetails(IRGenModule &IGM, CanSILFunctionType formalType,

0 commit comments

Comments
 (0)