[clang] 4c09289 - [clang] Add an API to retrieve implicit constructor arguments.
Dmitri Gribenko via cfe-commits
cfe-commits at lists.llvm.org
Tue May 19 00:36:20 PDT 2020
Author: Martin Böhme
Date: 2020-05-19T09:21:26+02:00
New Revision: 4c09289f635c4291c41fe4396afba4ba839d265b
URL: https://github.com/llvm/llvm-project/commit/4c09289f635c4291c41fe4396afba4ba839d265b
DIFF: https://github.com/llvm/llvm-project/commit/4c09289f635c4291c41fe4396afba4ba839d265b.diff
LOG: [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:
https://github.com/apple/swift/pull/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
Added:
Modified:
clang/include/clang/CodeGen/CodeGenABITypes.h
clang/lib/CodeGen/CGCXXABI.cpp
clang/lib/CodeGen/CGCXXABI.h
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGClass.cpp
clang/lib/CodeGen/CodeGenABITypes.cpp
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/CodeGen/MicrosoftCXXABI.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h
index 255e1603509e..0201f92074ec 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -39,6 +39,7 @@ class Type;
namespace clang {
class ASTContext;
+class CXXConstructorDecl;
class CXXRecordDecl;
class CXXMethodDecl;
class CodeGenOptions;
@@ -53,6 +54,16 @@ namespace CodeGen {
class CGFunctionInfo;
class CodeGenModule;
+/// Additional implicit arguments to add to a constructor argument list.
+struct ImplicitCXXConstructorArgs {
+ /// Implicit arguments to add before the explicit arguments, but after the
+ /// `*this` argument (which always comes first).
+ SmallVector<llvm::Value *, 1> Prefix;
+
+ /// Implicit arguments to add after the explicit arguments.
+ SmallVector<llvm::Value *, 1> Suffix;
+};
+
const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM,
const ObjCMethodDecl *MD,
QualType receiverType);
@@ -74,6 +85,11 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
FunctionType::ExtInfo info,
RequiredArgs args);
+/// Returns the implicit arguments to add to a complete, non-delegating C++
+/// constructor call.
+ImplicitCXXConstructorArgs
+getImplicitCXXConstructorArgs(CodeGenModule &CGM, const CXXConstructorDecl *D);
+
/// Returns null if the function type is incomplete and can't be lowered.
llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM,
const FunctionDecl *FD);
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 7ada4032b3ee..928fbaea8278 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -313,3 +313,20 @@ CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() {
std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) {
return std::vector<CharUnits>();
}
+
+CGCXXABI::AddedStructorArgCounts CGCXXABI::addImplicitConstructorArgs(
+ CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
+ bool ForVirtualBase, bool Delegating, CallArgList &Args) {
+ AddedStructorArgs AddedArgs =
+ getImplicitConstructorArgs(CGF, D, Type, ForVirtualBase, Delegating);
+ for (size_t i = 0; i < AddedArgs.Prefix.size(); ++i) {
+ Args.insert(Args.begin() + 1 + i,
+ CallArg(RValue::get(AddedArgs.Prefix[i].Value),
+ AddedArgs.Prefix[i].Type));
+ }
+ for (const auto &arg : AddedArgs.Suffix) {
+ Args.add(RValue::get(arg.Value), arg.Type);
+ }
+ return AddedStructorArgCounts(AddedArgs.Prefix.size(),
+ AddedArgs.Suffix.size());
+}
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index bff49be7a3c4..f5f378510950 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -16,6 +16,7 @@
#include "CodeGenFunction.h"
#include "clang/Basic/LLVM.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
namespace llvm {
class Constant;
@@ -287,24 +288,44 @@ class CGCXXABI {
/// Emit constructor variants required by this ABI.
virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;
- /// Notes how many arguments were added to the beginning (Prefix) and ending
- /// (Suffix) of an arg list.
+ /// Additional implicit arguments to add to the beginning (Prefix) and end
+ /// (Suffix) of a constructor / destructor arg list.
///
- /// Note that Prefix actually refers to the number of args *after* the first
- /// one: `this` arguments always come first.
+ /// Note that Prefix should actually be inserted *after* the first existing
+ /// arg; `this` arguments always come first.
struct AddedStructorArgs {
+ struct Arg {
+ llvm::Value *Value;
+ QualType Type;
+ };
+ SmallVector<Arg, 1> Prefix;
+ SmallVector<Arg, 1> Suffix;
+ AddedStructorArgs() = default;
+ AddedStructorArgs(SmallVector<Arg, 1> P, SmallVector<Arg, 1> S)
+ : Prefix(std::move(P)), Suffix(std::move(S)) {}
+ static AddedStructorArgs prefix(SmallVector<Arg, 1> Args) {
+ return {std::move(Args), {}};
+ }
+ static AddedStructorArgs suffix(SmallVector<Arg, 1> Args) {
+ return {{}, std::move(Args)};
+ }
+ };
+
+ /// Similar to AddedStructorArgs, but only notes the number of additional
+ /// arguments.
+ struct AddedStructorArgCounts {
unsigned Prefix = 0;
unsigned Suffix = 0;
- AddedStructorArgs() = default;
- AddedStructorArgs(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
- static AddedStructorArgs prefix(unsigned N) { return {N, 0}; }
- static AddedStructorArgs suffix(unsigned N) { return {0, N}; }
+ AddedStructorArgCounts() = default;
+ AddedStructorArgCounts(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
+ static AddedStructorArgCounts prefix(unsigned N) { return {N, 0}; }
+ static AddedStructorArgCounts suffix(unsigned N) { return {0, N}; }
};
/// Build the signature of the given constructor or destructor variant by
/// adding any required parameters. For convenience, ArgTys has been
/// initialized with the type of 'this'.
- virtual AddedStructorArgs
+ virtual AddedStructorArgCounts
buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) = 0;
@@ -365,14 +386,19 @@ class CGCXXABI {
/// Emit the ABI-specific prolog for the function.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;
+ virtual AddedStructorArgs
+ getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
+ CXXCtorType Type, bool ForVirtualBase,
+ bool Delegating) = 0;
+
/// Add any ABI-specific implicit arguments needed to call a constructor.
///
/// \return The number of arguments added at the beginning and end of the
/// call, which is typically zero or one.
- virtual AddedStructorArgs
+ AddedStructorArgCounts
addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
CXXCtorType Type, bool ForVirtualBase,
- bool Delegating, CallArgList &Args) = 0;
+ bool Delegating, CallArgList &Args);
/// Emit the destructor call.
virtual void EmitDestructorCall(CodeGenFunction &CGF,
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index b8bd8a780e50..6ae13c3de7ce 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -326,7 +326,7 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
if (PassParams)
appendParameterTypes(*this, argTypes, paramInfos, FTP);
- CGCXXABI::AddedStructorArgs AddedArgs =
+ CGCXXABI::AddedStructorArgCounts AddedArgs =
TheCXXABI.buildStructorSignature(GD, argTypes);
if (!paramInfos.empty()) {
// Note: prefix implies after the first param.
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 017a29e2361c..05e7aa7d17af 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2165,7 +2165,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
}
// Insert any ABI-specific implicit constructor arguments.
- CGCXXABI::AddedStructorArgs ExtraArgs =
+ CGCXXABI::AddedStructorArgCounts ExtraArgs =
CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase,
Delegating, Args);
diff --git a/clang/lib/CodeGen/CodeGenABITypes.cpp b/clang/lib/CodeGen/CodeGenABITypes.cpp
index fb8600029683..322cf45c47af 100644
--- a/clang/lib/CodeGen/CodeGenABITypes.cpp
+++ b/clang/lib/CodeGen/CodeGenABITypes.cpp
@@ -16,7 +16,9 @@
//===----------------------------------------------------------------------===//
#include "clang/CodeGen/CodeGenABITypes.h"
+#include "CGCXXABI.h"
#include "CGRecordLayout.h"
+#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Lex/HeaderSearchOptions.h"
@@ -68,6 +70,30 @@ CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
info, {}, args);
}
+ImplicitCXXConstructorArgs
+CodeGen::getImplicitCXXConstructorArgs(CodeGenModule &CGM,
+ const CXXConstructorDecl *D) {
+ // We have to create a dummy CodeGenFunction here to pass to
+ // getImplicitConstructorArgs(). In some cases (base and delegating
+ // constructor calls), getImplicitConstructorArgs() can reach into the
+ // CodeGenFunction to find parameters of the calling constructor to pass on to
+ // the called constructor, but that can't happen here because we're asking for
+ // the args for a complete, non-delegating constructor call.
+ CodeGenFunction CGF(CGM, /* suppressNewContext= */ true);
+ CGCXXABI::AddedStructorArgs addedArgs =
+ CGM.getCXXABI().getImplicitConstructorArgs(CGF, D, Ctor_Complete,
+ /* ForVirtualBase= */ false,
+ /* Delegating= */ false);
+ ImplicitCXXConstructorArgs implicitArgs;
+ for (const auto &arg : addedArgs.Prefix) {
+ implicitArgs.Prefix.push_back(arg.Value);
+ }
+ for (const auto &arg : addedArgs.Suffix) {
+ implicitArgs.Suffix.push_back(arg.Value);
+ }
+ return implicitArgs;
+}
+
llvm::FunctionType *
CodeGen::convertFreeFunctionType(CodeGenModule &CGM, const FunctionDecl *FD) {
assert(FD != nullptr && "Expected a non-null function declaration!");
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index ceef143e9017..af3714b5b0c4 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -203,7 +203,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
void EmitCXXConstructors(const CXXConstructorDecl *D) override;
- AddedStructorArgs
+ AddedStructorArgCounts
buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) override;
@@ -222,10 +222,11 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
- AddedStructorArgs
- addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
- CXXCtorType Type, bool ForVirtualBase,
- bool Delegating, CallArgList &Args) override;
+ AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
+ const CXXConstructorDecl *D,
+ CXXCtorType Type,
+ bool ForVirtualBase,
+ bool Delegating) override;
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
@@ -1550,7 +1551,7 @@ void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
}
}
-CGCXXABI::AddedStructorArgs
+CGCXXABI::AddedStructorArgCounts
ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) {
ASTContext &Context = getContext();
@@ -1564,9 +1565,9 @@ ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
cast<CXXMethodDecl>(GD.getDecl())->getParent()->getNumVBases() != 0) {
ArgTys.insert(ArgTys.begin() + 1,
Context.getPointerType(Context.VoidPtrTy));
- return AddedStructorArgs::prefix(1);
+ return AddedStructorArgCounts::prefix(1);
}
- return AddedStructorArgs{};
+ return AddedStructorArgCounts{};
}
void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -1632,9 +1633,9 @@ void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
}
-CGCXXABI::AddedStructorArgs ItaniumCXXABI::addImplicitConstructorArgs(
+CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
- bool ForVirtualBase, bool Delegating, CallArgList &Args) {
+ bool ForVirtualBase, bool Delegating) {
if (!NeedsVTTParameter(GlobalDecl(D, Type)))
return AddedStructorArgs{};
@@ -1642,8 +1643,7 @@ CGCXXABI::AddedStructorArgs ItaniumCXXABI::addImplicitConstructorArgs(
llvm::Value *VTT =
CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating);
QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
- Args.insert(Args.begin() + 1, CallArg(RValue::get(VTT), VTTTy));
- return AddedStructorArgs::prefix(1); // Added one arg.
+ return AddedStructorArgs::prefix({{VTT, VTTTy}});
}
void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 4a5d4997fe43..76881e973f41 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -206,7 +206,7 @@ class MicrosoftCXXABI : public CGCXXABI {
// lacks a definition for the destructor, non-base destructors must always
// delegate to or alias the base destructor.
- AddedStructorArgs
+ AddedStructorArgCounts
buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) override;
@@ -253,10 +253,11 @@ class MicrosoftCXXABI : public CGCXXABI {
void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
- AddedStructorArgs
- addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
- CXXCtorType Type, bool ForVirtualBase,
- bool Delegating, CallArgList &Args) override;
+ AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
+ const CXXConstructorDecl *D,
+ CXXCtorType Type,
+ bool ForVirtualBase,
+ bool Delegating) override;
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
@@ -1261,10 +1262,10 @@ void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
}
}
-CGCXXABI::AddedStructorArgs
+CGCXXABI::AddedStructorArgCounts
MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) {
- AddedStructorArgs Added;
+ AddedStructorArgCounts Added;
// TODO: 'for base' flag
if (isa<CXXDestructorDecl>(GD.getDecl()) &&
GD.getDtorType() == Dtor_Deleting) {
@@ -1553,9 +1554,9 @@ void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
}
}
-CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
+CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
- bool ForVirtualBase, bool Delegating, CallArgList &Args) {
+ bool ForVirtualBase, bool Delegating) {
assert(Type == Ctor_Complete || Type == Ctor_Base);
// Check if we need a 'most_derived' parameter.
@@ -1570,13 +1571,10 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
} else {
MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
}
- RValue RV = RValue::get(MostDerivedArg);
if (FPT->isVariadic()) {
- Args.insert(Args.begin() + 1, CallArg(RV, getContext().IntTy));
- return AddedStructorArgs::prefix(1);
+ return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
}
- Args.add(RV, getContext().IntTy);
- return AddedStructorArgs::suffix(1);
+ return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
}
void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
@@ -4009,7 +4007,7 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
CGF.EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
// Insert any ABI-specific implicit constructor arguments.
- AddedStructorArgs ExtraArgs =
+ AddedStructorArgCounts ExtraArgs =
addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
/*ForVirtualBase=*/false,
/*Delegating=*/false, Args);
More information about the cfe-commits
mailing list