Skip to content

Commit 1e4d4bb

Browse files
authored
[Clang][NFC] Refactor operator delete argument handling (#160554)
This change moves the getUsualDeleteParams function into the FunctionDecl class so that it can be shared between LLVM IR and CIR codegen.
1 parent e2f8bfc commit 1e4d4bb

File tree

5 files changed

+65
-113
lines changed

5 files changed

+65
-113
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class TypeAliasTemplateDecl;
8080
class UnresolvedSetImpl;
8181
class VarTemplateDecl;
8282
enum class ImplicitParamKind;
83+
struct UsualDeleteParams;
8384

8485
// Holds a constraint expression along with a pack expansion index, if
8586
// expanded.
@@ -2646,6 +2647,8 @@ class FunctionDecl : public DeclaratorDecl,
26462647
bool isTypeAwareOperatorNewOrDelete() const;
26472648
void setIsTypeAwareOperatorNewOrDelete(bool IsTypeAwareOperator = true);
26482649

2650+
UsualDeleteParams getUsualDeleteParams() const;
2651+
26492652
/// Compute the language linkage.
26502653
LanguageLinkage getLanguageLinkage() const;
26512654

clang/include/clang/AST/ExprCXX.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,6 +2342,14 @@ struct ImplicitDeallocationParameters {
23422342
SizedDeallocationMode PassSize;
23432343
};
23442344

2345+
/// The parameters to pass to a usual operator delete.
2346+
struct UsualDeleteParams {
2347+
TypeAwareAllocationMode TypeAwareDelete = TypeAwareAllocationMode::No;
2348+
bool DestroyingDelete = false;
2349+
bool Size = false;
2350+
AlignedAllocationMode Alignment = AlignedAllocationMode::No;
2351+
};
2352+
23452353
/// Represents a new-expression for memory allocation and constructor
23462354
/// calls, e.g: "new CXXNewExpr(foo)".
23472355
class CXXNewExpr final

clang/lib/AST/Decl.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3552,6 +3552,53 @@ void FunctionDecl::setIsTypeAwareOperatorNewOrDelete(bool IsTypeAware) {
35523552
getASTContext().setIsTypeAwareOperatorNewOrDelete(this, IsTypeAware);
35533553
}
35543554

3555+
UsualDeleteParams FunctionDecl::getUsualDeleteParams() const {
3556+
UsualDeleteParams Params;
3557+
3558+
// This function should only be called for operator delete declarations.
3559+
assert(getDeclName().isAnyOperatorDelete());
3560+
if (!getDeclName().isAnyOperatorDelete())
3561+
return Params;
3562+
3563+
const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
3564+
auto AI = FPT->param_type_begin(), AE = FPT->param_type_end();
3565+
3566+
if (isTypeAwareOperatorNewOrDelete()) {
3567+
Params.TypeAwareDelete = TypeAwareAllocationMode::Yes;
3568+
assert(AI != AE);
3569+
++AI;
3570+
}
3571+
3572+
// The first argument after the type-identity parameter (if any) is
3573+
// always a void* (or C* for a destroying operator delete for class
3574+
// type C).
3575+
++AI;
3576+
3577+
// The next parameter may be a std::destroying_delete_t.
3578+
if (isDestroyingOperatorDelete()) {
3579+
assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
3580+
Params.DestroyingDelete = true;
3581+
assert(AI != AE);
3582+
++AI;
3583+
}
3584+
3585+
// Figure out what other parameters we should be implicitly passing.
3586+
if (AI != AE && (*AI)->isIntegerType()) {
3587+
Params.Size = true;
3588+
++AI;
3589+
} else
3590+
assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
3591+
3592+
if (AI != AE && (*AI)->isAlignValT()) {
3593+
Params.Alignment = AlignedAllocationMode::Yes;
3594+
++AI;
3595+
} else
3596+
assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
3597+
3598+
assert(AI == AE && "unexpected usual deallocation function parameter");
3599+
return Params;
3600+
}
3601+
35553602
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
35563603
return getDeclLanguageLinkage(*this);
35573604
}

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -210,60 +210,6 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorCall(
210210
return emitCall(fnInfo, callee, returnValue, args, nullptr, loc);
211211
}
212212

213-
namespace {
214-
/// The parameters to pass to a usual operator delete.
215-
struct UsualDeleteParams {
216-
TypeAwareAllocationMode typeAwareDelete = TypeAwareAllocationMode::No;
217-
bool destroyingDelete = false;
218-
bool size = false;
219-
AlignedAllocationMode alignment = AlignedAllocationMode::No;
220-
};
221-
} // namespace
222-
223-
// FIXME(cir): this should be shared with LLVM codegen
224-
static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *fd) {
225-
UsualDeleteParams params;
226-
227-
const FunctionProtoType *fpt = fd->getType()->castAs<FunctionProtoType>();
228-
auto ai = fpt->param_type_begin(), ae = fpt->param_type_end();
229-
230-
if (fd->isTypeAwareOperatorNewOrDelete()) {
231-
params.typeAwareDelete = TypeAwareAllocationMode::Yes;
232-
assert(ai != ae);
233-
++ai;
234-
}
235-
236-
// The first argument after the type-identity parameter (if any) is
237-
// always a void* (or C* for a destroying operator delete for class
238-
// type C).
239-
++ai;
240-
241-
// The next parameter may be a std::destroying_delete_t.
242-
if (fd->isDestroyingOperatorDelete()) {
243-
params.destroyingDelete = true;
244-
assert(ai != ae);
245-
++ai;
246-
}
247-
248-
// Figure out what other parameters we should be implicitly passing.
249-
if (ai != ae && (*ai)->isIntegerType()) {
250-
params.size = true;
251-
++ai;
252-
} else {
253-
assert(!isTypeAwareAllocation(params.typeAwareDelete));
254-
}
255-
256-
if (ai != ae && (*ai)->isAlignValT()) {
257-
params.alignment = AlignedAllocationMode::Yes;
258-
++ai;
259-
} else {
260-
assert(!isTypeAwareAllocation(params.typeAwareDelete));
261-
}
262-
263-
assert(ai == ae && "unexpected usual deallocation function parameter");
264-
return params;
265-
}
266-
267213
static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
268214
unsigned minElements,
269215
mlir::Value &numElements,
@@ -616,11 +562,11 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
616562
const auto *deleteFTy = deleteFD->getType()->castAs<FunctionProtoType>();
617563
CallArgList deleteArgs;
618564

619-
UsualDeleteParams params = getUsualDeleteParams(deleteFD);
565+
UsualDeleteParams params = deleteFD->getUsualDeleteParams();
620566
auto paramTypeIt = deleteFTy->param_type_begin();
621567

622568
// Pass std::type_identity tag if present
623-
if (isTypeAwareAllocation(params.typeAwareDelete))
569+
if (isTypeAwareAllocation(params.TypeAwareDelete))
624570
cgm.errorNYI(deleteFD->getSourceRange(),
625571
"emitDeleteCall: type aware delete");
626572

@@ -631,12 +577,12 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
631577
deleteArgs.add(RValue::get(deletePtr), argTy);
632578

633579
// Pass the std::destroying_delete tag if present.
634-
if (params.destroyingDelete)
580+
if (params.DestroyingDelete)
635581
cgm.errorNYI(deleteFD->getSourceRange(),
636582
"emitDeleteCall: destroying delete");
637583

638584
// Pass the size if the delete function has a size_t parameter.
639-
if (params.size) {
585+
if (params.Size) {
640586
QualType sizeType = *paramTypeIt++;
641587
CharUnits deleteTypeSize = getContext().getTypeSizeInChars(deleteTy);
642588
assert(mlir::isa<cir::IntType>(convertType(sizeType)) &&
@@ -648,7 +594,7 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
648594
}
649595

650596
// Pass the alignment if the delete function has an align_val_t parameter.
651-
if (isAlignedAllocation(params.alignment))
597+
if (isAlignedAllocation(params.Alignment))
652598
cgm.errorNYI(deleteFD->getSourceRange(),
653599
"emitDeleteCall: aligned allocation");
654600

clang/lib/CodeGen/CGExprCXX.cpp

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,58 +1376,6 @@ RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
13761376
llvm_unreachable("predeclared global operator new/delete is missing");
13771377
}
13781378

1379-
namespace {
1380-
/// The parameters to pass to a usual operator delete.
1381-
struct UsualDeleteParams {
1382-
TypeAwareAllocationMode TypeAwareDelete = TypeAwareAllocationMode::No;
1383-
bool DestroyingDelete = false;
1384-
bool Size = false;
1385-
AlignedAllocationMode Alignment = AlignedAllocationMode::No;
1386-
};
1387-
}
1388-
1389-
static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *FD) {
1390-
UsualDeleteParams Params;
1391-
1392-
const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
1393-
auto AI = FPT->param_type_begin(), AE = FPT->param_type_end();
1394-
1395-
if (FD->isTypeAwareOperatorNewOrDelete()) {
1396-
Params.TypeAwareDelete = TypeAwareAllocationMode::Yes;
1397-
assert(AI != AE);
1398-
++AI;
1399-
}
1400-
1401-
// The first argument after the type-identity parameter (if any) is
1402-
// always a void* (or C* for a destroying operator delete for class
1403-
// type C).
1404-
++AI;
1405-
1406-
// The next parameter may be a std::destroying_delete_t.
1407-
if (FD->isDestroyingOperatorDelete()) {
1408-
assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
1409-
Params.DestroyingDelete = true;
1410-
assert(AI != AE);
1411-
++AI;
1412-
}
1413-
1414-
// Figure out what other parameters we should be implicitly passing.
1415-
if (AI != AE && (*AI)->isIntegerType()) {
1416-
Params.Size = true;
1417-
++AI;
1418-
} else
1419-
assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
1420-
1421-
if (AI != AE && (*AI)->isAlignValT()) {
1422-
Params.Alignment = AlignedAllocationMode::Yes;
1423-
++AI;
1424-
} else
1425-
assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
1426-
1427-
assert(AI == AE && "unexpected usual deallocation function parameter");
1428-
return Params;
1429-
}
1430-
14311379
namespace {
14321380
/// A cleanup to call the given 'operator delete' function upon abnormal
14331381
/// exit from a new expression. Templated on a traits type that deals with
@@ -1505,7 +1453,7 @@ namespace {
15051453
} else {
15061454
// For a non-placement new-expression, 'operator delete' can take a
15071455
// size and/or an alignment if it has the right parameters.
1508-
Params = getUsualDeleteParams(OperatorDelete);
1456+
Params = OperatorDelete->getUsualDeleteParams();
15091457
}
15101458

15111459
assert(!Params.DestroyingDelete &&
@@ -1838,7 +1786,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
18381786
const auto *DeleteFTy = DeleteFD->getType()->castAs<FunctionProtoType>();
18391787
CallArgList DeleteArgs;
18401788

1841-
auto Params = getUsualDeleteParams(DeleteFD);
1789+
auto Params = DeleteFD->getUsualDeleteParams();
18421790
auto ParamTypeIt = DeleteFTy->param_type_begin();
18431791

18441792
std::optional<llvm::AllocaInst *> TagAlloca;

0 commit comments

Comments
 (0)