Skip to content

Commit c1f3bf0

Browse files
committed
[clang] Add an API to retrieve implicit constructor arguments.
Summary: This is needed in Swift for C++ interop -- see here for the corresponding Swift change: swiftlang/swift#30630 As part of this change, I've had to make some changes to the interface of CGCXXABI to return the additional parameters separately rather than adding them directly to a `CallArgList`. Reviewers: rjmccall Reviewed By: rjmccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D79942
1 parent 771a1d8 commit c1f3bf0

File tree

8 files changed

+123
-40
lines changed

8 files changed

+123
-40
lines changed

clang/include/clang/CodeGen/CodeGenABITypes.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace llvm {
3838

3939
namespace clang {
4040
class ASTContext;
41+
class CXXConstructorDecl;
4142
class CXXRecordDecl;
4243
class CXXMethodDecl;
4344
class CodeGenOptions;
@@ -52,6 +53,16 @@ namespace CodeGen {
5253
class CGFunctionInfo;
5354
class CodeGenModule;
5455

56+
/// Additional implicit arguments to add to a constructor argument list.
57+
struct ImplicitCXXConstructorArgs {
58+
/// Implicit arguments to add before the explicit arguments, but after the
59+
/// `*this` argument (which always comes first).
60+
SmallVector<llvm::Value *, 1> Prefix;
61+
62+
/// Implicit arguments to add after the explicit arguments.
63+
SmallVector<llvm::Value *, 1> Suffix;
64+
};
65+
5566
const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM,
5667
const ObjCMethodDecl *MD,
5768
QualType receiverType);
@@ -73,6 +84,11 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
7384
FunctionType::ExtInfo info,
7485
RequiredArgs args);
7586

87+
/// Returns the implicit arguments to add to a complete, non-delegating C++
88+
/// constructor call.
89+
ImplicitCXXConstructorArgs
90+
getImplicitCXXConstructorArgs(CodeGenModule &CGM, const CXXConstructorDecl *D);
91+
7692
/// Returns null if the function type is incomplete and can't be lowered.
7793
llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM,
7894
const FunctionDecl *FD);

clang/lib/CodeGen/CGCXXABI.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,20 @@ CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() {
313313
std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) {
314314
return std::vector<CharUnits>();
315315
}
316+
317+
CGCXXABI::AddedStructorArgCounts CGCXXABI::addImplicitConstructorArgs(
318+
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
319+
bool ForVirtualBase, bool Delegating, CallArgList &Args) {
320+
AddedStructorArgs AddedArgs =
321+
getImplicitConstructorArgs(CGF, D, Type, ForVirtualBase, Delegating);
322+
for (size_t i = 0; i < AddedArgs.Prefix.size(); ++i) {
323+
Args.insert(Args.begin() + 1 + i,
324+
CallArg(RValue::get(AddedArgs.Prefix[i].Value),
325+
AddedArgs.Prefix[i].Type));
326+
}
327+
for (const auto &arg : AddedArgs.Suffix) {
328+
Args.add(RValue::get(arg.Value), arg.Type);
329+
}
330+
return AddedStructorArgCounts(AddedArgs.Prefix.size(),
331+
AddedArgs.Suffix.size());
332+
}

clang/lib/CodeGen/CGCXXABI.h

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "CodeGenFunction.h"
1818
#include "clang/Basic/LLVM.h"
19+
#include "clang/CodeGen/CodeGenABITypes.h"
1920

2021
namespace llvm {
2122
class Constant;
@@ -287,24 +288,44 @@ class CGCXXABI {
287288
/// Emit constructor variants required by this ABI.
288289
virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;
289290

290-
/// Notes how many arguments were added to the beginning (Prefix) and ending
291-
/// (Suffix) of an arg list.
291+
/// Additional implicit arguments to add to the beginning (Prefix) and end
292+
/// (Suffix) of a constructor / destructor arg list.
292293
///
293-
/// Note that Prefix actually refers to the number of args *after* the first
294-
/// one: `this` arguments always come first.
294+
/// Note that Prefix should actually be inserted *after* the first existing
295+
/// arg; `this` arguments always come first.
295296
struct AddedStructorArgs {
297+
struct Arg {
298+
llvm::Value *Value;
299+
QualType Type;
300+
};
301+
SmallVector<Arg, 1> Prefix;
302+
SmallVector<Arg, 1> Suffix;
303+
AddedStructorArgs() = default;
304+
AddedStructorArgs(SmallVector<Arg, 1> P, SmallVector<Arg, 1> S)
305+
: Prefix(std::move(P)), Suffix(std::move(S)) {}
306+
static AddedStructorArgs prefix(SmallVector<Arg, 1> Args) {
307+
return {std::move(Args), {}};
308+
}
309+
static AddedStructorArgs suffix(SmallVector<Arg, 1> Args) {
310+
return {{}, std::move(Args)};
311+
}
312+
};
313+
314+
/// Similar to AddedStructorArgs, but only notes the number of additional
315+
/// arguments.
316+
struct AddedStructorArgCounts {
296317
unsigned Prefix = 0;
297318
unsigned Suffix = 0;
298-
AddedStructorArgs() = default;
299-
AddedStructorArgs(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
300-
static AddedStructorArgs prefix(unsigned N) { return {N, 0}; }
301-
static AddedStructorArgs suffix(unsigned N) { return {0, N}; }
319+
AddedStructorArgCounts() = default;
320+
AddedStructorArgCounts(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
321+
static AddedStructorArgCounts prefix(unsigned N) { return {N, 0}; }
322+
static AddedStructorArgCounts suffix(unsigned N) { return {0, N}; }
302323
};
303324

304325
/// Build the signature of the given constructor or destructor variant by
305326
/// adding any required parameters. For convenience, ArgTys has been
306327
/// initialized with the type of 'this'.
307-
virtual AddedStructorArgs
328+
virtual AddedStructorArgCounts
308329
buildStructorSignature(GlobalDecl GD,
309330
SmallVectorImpl<CanQualType> &ArgTys) = 0;
310331

@@ -365,14 +386,19 @@ class CGCXXABI {
365386
/// Emit the ABI-specific prolog for the function.
366387
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;
367388

389+
virtual AddedStructorArgs
390+
getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
391+
CXXCtorType Type, bool ForVirtualBase,
392+
bool Delegating) = 0;
393+
368394
/// Add any ABI-specific implicit arguments needed to call a constructor.
369395
///
370396
/// \return The number of arguments added at the beginning and end of the
371397
/// call, which is typically zero or one.
372-
virtual AddedStructorArgs
398+
AddedStructorArgCounts
373399
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
374400
CXXCtorType Type, bool ForVirtualBase,
375-
bool Delegating, CallArgList &Args) = 0;
401+
bool Delegating, CallArgList &Args);
376402

377403
/// Emit the destructor call.
378404
virtual void EmitDestructorCall(CodeGenFunction &CGF,

clang/lib/CodeGen/CGCall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
325325
if (PassParams)
326326
appendParameterTypes(*this, argTypes, paramInfos, FTP);
327327

328-
CGCXXABI::AddedStructorArgs AddedArgs =
328+
CGCXXABI::AddedStructorArgCounts AddedArgs =
329329
TheCXXABI.buildStructorSignature(GD, argTypes);
330330
if (!paramInfos.empty()) {
331331
// Note: prefix implies after the first param.

clang/lib/CodeGen/CGClass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2168,7 +2168,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
21682168
}
21692169

21702170
// Insert any ABI-specific implicit constructor arguments.
2171-
CGCXXABI::AddedStructorArgs ExtraArgs =
2171+
CGCXXABI::AddedStructorArgCounts ExtraArgs =
21722172
CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase,
21732173
Delegating, Args);
21742174

clang/lib/CodeGen/CodeGenABITypes.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
//===----------------------------------------------------------------------===//
1717

1818
#include "clang/CodeGen/CodeGenABITypes.h"
19+
#include "CGCXXABI.h"
1920
#include "CGRecordLayout.h"
21+
#include "CodeGenFunction.h"
2022
#include "CodeGenModule.h"
2123
#include "clang/CodeGen/CGFunctionInfo.h"
2224
#include "clang/Lex/HeaderSearchOptions.h"
@@ -63,6 +65,30 @@ CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
6365
info, {}, args);
6466
}
6567

68+
ImplicitCXXConstructorArgs
69+
CodeGen::getImplicitCXXConstructorArgs(CodeGenModule &CGM,
70+
const CXXConstructorDecl *D) {
71+
// We have to create a dummy CodeGenFunction here to pass to
72+
// getImplicitConstructorArgs(). In some cases (base and delegating
73+
// constructor calls), getImplicitConstructorArgs() can reach into the
74+
// CodeGenFunction to find parameters of the calling constructor to pass on to
75+
// the called constructor, but that can't happen here because we're asking for
76+
// the args for a complete, non-delegating constructor call.
77+
CodeGenFunction CGF(CGM, /* suppressNewContext= */ true);
78+
CGCXXABI::AddedStructorArgs addedArgs =
79+
CGM.getCXXABI().getImplicitConstructorArgs(CGF, D, Ctor_Complete,
80+
/* ForVirtualBase= */ false,
81+
/* Delegating= */ false);
82+
ImplicitCXXConstructorArgs implicitArgs;
83+
for (const auto &arg : addedArgs.Prefix) {
84+
implicitArgs.Prefix.push_back(arg.Value);
85+
}
86+
for (const auto &arg : addedArgs.Suffix) {
87+
implicitArgs.Suffix.push_back(arg.Value);
88+
}
89+
return implicitArgs;
90+
}
91+
6692
llvm::FunctionType *
6793
CodeGen::convertFreeFunctionType(CodeGenModule &CGM, const FunctionDecl *FD) {
6894
assert(FD != nullptr && "Expected a non-null function declaration!");

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
204204

205205
void EmitCXXConstructors(const CXXConstructorDecl *D) override;
206206

207-
AddedStructorArgs
207+
AddedStructorArgCounts
208208
buildStructorSignature(GlobalDecl GD,
209209
SmallVectorImpl<CanQualType> &ArgTys) override;
210210

@@ -223,10 +223,11 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
223223

224224
void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
225225

226-
AddedStructorArgs
227-
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
228-
CXXCtorType Type, bool ForVirtualBase,
229-
bool Delegating, CallArgList &Args) override;
226+
AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
227+
const CXXConstructorDecl *D,
228+
CXXCtorType Type,
229+
bool ForVirtualBase,
230+
bool Delegating) override;
230231

231232
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
232233
CXXDtorType Type, bool ForVirtualBase,
@@ -1621,7 +1622,7 @@ void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
16211622
}
16221623
}
16231624

1624-
CGCXXABI::AddedStructorArgs
1625+
CGCXXABI::AddedStructorArgCounts
16251626
ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
16261627
SmallVectorImpl<CanQualType> &ArgTys) {
16271628
ASTContext &Context = getContext();
@@ -1635,9 +1636,9 @@ ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
16351636
cast<CXXMethodDecl>(GD.getDecl())->getParent()->getNumVBases() != 0) {
16361637
ArgTys.insert(ArgTys.begin() + 1,
16371638
Context.getPointerType(Context.VoidPtrTy));
1638-
return AddedStructorArgs::prefix(1);
1639+
return AddedStructorArgCounts::prefix(1);
16391640
}
1640-
return AddedStructorArgs{};
1641+
return AddedStructorArgCounts{};
16411642
}
16421643

16431644
void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -1703,18 +1704,17 @@ void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
17031704
CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
17041705
}
17051706

1706-
CGCXXABI::AddedStructorArgs ItaniumCXXABI::addImplicitConstructorArgs(
1707+
CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
17071708
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
1708-
bool ForVirtualBase, bool Delegating, CallArgList &Args) {
1709+
bool ForVirtualBase, bool Delegating) {
17091710
if (!NeedsVTTParameter(GlobalDecl(D, Type)))
17101711
return AddedStructorArgs{};
17111712

17121713
// Insert the implicit 'vtt' argument as the second argument.
17131714
llvm::Value *VTT =
17141715
CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating);
17151716
QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1716-
Args.insert(Args.begin() + 1, CallArg(RValue::get(VTT), VTTTy));
1717-
return AddedStructorArgs::prefix(1); // Added one arg.
1717+
return AddedStructorArgs::prefix({{VTT, VTTTy}});
17181718
}
17191719

17201720
void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,

clang/lib/CodeGen/MicrosoftCXXABI.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class MicrosoftCXXABI : public CGCXXABI {
206206
// lacks a definition for the destructor, non-base destructors must always
207207
// delegate to or alias the base destructor.
208208

209-
AddedStructorArgs
209+
AddedStructorArgCounts
210210
buildStructorSignature(GlobalDecl GD,
211211
SmallVectorImpl<CanQualType> &ArgTys) override;
212212

@@ -253,10 +253,11 @@ class MicrosoftCXXABI : public CGCXXABI {
253253

254254
void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
255255

256-
AddedStructorArgs
257-
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
258-
CXXCtorType Type, bool ForVirtualBase,
259-
bool Delegating, CallArgList &Args) override;
256+
AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
257+
const CXXConstructorDecl *D,
258+
CXXCtorType Type,
259+
bool ForVirtualBase,
260+
bool Delegating) override;
260261

261262
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
262263
CXXDtorType Type, bool ForVirtualBase,
@@ -1261,10 +1262,10 @@ void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
12611262
}
12621263
}
12631264

1264-
CGCXXABI::AddedStructorArgs
1265+
CGCXXABI::AddedStructorArgCounts
12651266
MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
12661267
SmallVectorImpl<CanQualType> &ArgTys) {
1267-
AddedStructorArgs Added;
1268+
AddedStructorArgCounts Added;
12681269
// TODO: 'for base' flag
12691270
if (isa<CXXDestructorDecl>(GD.getDecl()) &&
12701271
GD.getDtorType() == Dtor_Deleting) {
@@ -1553,9 +1554,9 @@ void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
15531554
}
15541555
}
15551556

1556-
CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
1557+
CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
15571558
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
1558-
bool ForVirtualBase, bool Delegating, CallArgList &Args) {
1559+
bool ForVirtualBase, bool Delegating) {
15591560
assert(Type == Ctor_Complete || Type == Ctor_Base);
15601561

15611562
// Check if we need a 'most_derived' parameter.
@@ -1570,13 +1571,10 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
15701571
} else {
15711572
MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
15721573
}
1573-
RValue RV = RValue::get(MostDerivedArg);
15741574
if (FPT->isVariadic()) {
1575-
Args.insert(Args.begin() + 1, CallArg(RV, getContext().IntTy));
1576-
return AddedStructorArgs::prefix(1);
1575+
return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
15771576
}
1578-
Args.add(RV, getContext().IntTy);
1579-
return AddedStructorArgs::suffix(1);
1577+
return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
15801578
}
15811579

15821580
void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
@@ -4000,7 +3998,7 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
40003998
CGF.EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
40013999

40024000
// Insert any ABI-specific implicit constructor arguments.
4003-
AddedStructorArgs ExtraArgs =
4001+
AddedStructorArgCounts ExtraArgs =
40044002
addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
40054003
/*ForVirtualBase=*/false,
40064004
/*Delegating=*/false, Args);

0 commit comments

Comments
 (0)