aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorAmy Huang <akhuang@google.com>2023-06-23 11:41:44 -0700
committerAmy Huang <akhuang@google.com>2023-07-26 16:13:36 -0700
commit27dab4d305acb6e0935e014c061c5317016ae2b3 (patch)
tree6d7caa44b14555d82c74c767d114503eacc73388 /clang/lib/CodeGen/CodeGenFunction.cpp
parent63458d92e524f00b8a3614b5772c270151b049e8 (diff)
downloadllvm-27dab4d305acb6e0935e014c061c5317016ae2b3.zip
llvm-27dab4d305acb6e0935e014c061c5317016ae2b3.tar.gz
llvm-27dab4d305acb6e0935e014c061c5317016ae2b3.tar.bz2
Reland "Try to implement lambdas with inalloca parameters by forwarding without use of inallocas."t
This reverts commit 8ed7aa59f489715d39d32e72a787b8e75cfda151. Differential Revision: https://reviews.llvm.org/D154007
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index fab70b6..d71fda2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -683,6 +683,19 @@ static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) {
return true;
}
+bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) {
+ const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+ return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
+}
+
+bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) {
+ return getTarget().getTriple().getArch() == llvm::Triple::x86 &&
+ getTarget().getCXXABI().isMicrosoft() &&
+ llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {
+ return isInAllocaArgument(CGM.getCXXABI(), P->getType());
+ });
+}
+
/// Return the UBSan prologue signature for \p FD if one is available.
static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
const FunctionDecl *FD) {
@@ -1447,6 +1460,17 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// The lambda static invoker function is special, because it forwards or
// clones the body of the function call operator (but is actually static).
EmitLambdaStaticInvokeBody(cast<CXXMethodDecl>(FD));
+ } else if (isa<CXXMethodDecl>(FD) &&
+ isLambdaCallOperator(cast<CXXMethodDecl>(FD)) &&
+ !FnInfo.isDelegateCall() &&
+ cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
+ hasInAllocaArg(cast<CXXMethodDecl>(FD))) {
+ // If emitting a lambda with static invoker on X86 Windows, change
+ // the call operator body.
+ // Make sure that this is a call operator with an inalloca arg and check
+ // for delegate call to make sure this is the original call op and not the
+ // new forwarding function for the static invoker.
+ EmitLambdaInAllocaCallOpBody(cast<CXXMethodDecl>(FD));
} else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) &&
(cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {