Skip to content

Commit 68ff6ef

Browse files
committed
add CXXCtorDtor attribute
1 parent 32e3971 commit 68ff6ef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+224
-172
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,39 @@ def GlobalDtorAttr : CIR_GlobalCtorDtor<"Dtor", "dtor",
13001300
"A function with this attribute excutes before module unloading"
13011301
>;
13021302

1303+
class CIR_CXXCtorDtor<string name, string attrMnemonic, string sum, string desc>
1304+
: CIR_Attr<name, attrMnemonic> {
1305+
let summary = sum;
1306+
let description = desc;
1307+
1308+
let parameters = (ins "mlir::StringAttr":$name);
1309+
let assemblyFormat = [{
1310+
`<`
1311+
$name
1312+
`>`
1313+
}];
1314+
let builders = [
1315+
AttrBuilder<(ins "llvm::StringRef":$name), [{
1316+
return $_get($_ctxt, mlir::StringAttr::get($_ctxt, name));
1317+
}]>,
1318+
AttrBuilderWithInferredContext<(ins "mlir::StringAttr":$name),
1319+
[{
1320+
return $_get(name.getContext(), name);
1321+
}]>
1322+
];
1323+
let skipDefaultBuilders = 1;
1324+
}
1325+
1326+
def CXXCtorAttr
1327+
: CIR_CXXCtorDtor<"CXXCtor", "cxx_ctor",
1328+
"Marks a function as a CXX constructor",
1329+
"Functions with this attribute are CXX constructors">;
1330+
1331+
def CXXDtorAttr
1332+
: CIR_CXXCtorDtor<"CXXDtor", "cxx_dtor",
1333+
"Marks a function as a CXX destructor",
1334+
"Functions with this attribute are CXX destructors">;
1335+
13031336
def BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> {
13041337
let summary = "Represents a bit field info";
13051338
let description = [{

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,9 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo,
424424
const CallArgList &CallArgs,
425425
cir::CIRCallOpInterface *callOrTryCall,
426426
bool IsMustTail, mlir::Location loc,
427-
std::optional<const clang::CallExpr *> E) {
427+
std::optional<const clang::CallExpr *> E,
428+
std::optional<cir::CXXCtorAttr> cxxCtor,
429+
std::optional<cir::CXXDtorAttr> cxxDtor) {
428430
auto builder = CGM.getBuilder();
429431
// FIXME: We no longer need the types from CallArgs; lift up and simplify
430432

@@ -653,6 +655,12 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo,
653655
callLikeOp->setAttr("ast",
654656
cir::ASTCallExprAttr::get(&getMLIRContext(), *E));
655657

658+
if (cxxCtor)
659+
callLikeOp->setAttr("cxx_ctor", *cxxCtor);
660+
661+
if (cxxDtor)
662+
callLikeOp->setAttr("cxx_dtor", *cxxDtor);
663+
656664
if (callOrTryCall)
657665
*callOrTryCall = callLikeOp;
658666
return callLikeOp;

clang/lib/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2012,7 +2012,11 @@ void CIRGenFunction::emitCXXConstructorCall(
20122012
Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
20132013
CIRGenCallee Callee = CIRGenCallee::forDirect(CalleePtr, GlobalDecl(D, Type));
20142014
cir::CIRCallOpInterface C;
2015-
emitCall(Info, Callee, ReturnValueSlot(), Args, &C, false, getLoc(Loc));
2015+
2016+
auto cxxCtor = cir::CXXCtorAttr::get(
2017+
&getMLIRContext(), getContext().getRecordType(ClassDecl).getAsString());
2018+
emitCall(Info, Callee, ReturnValueSlot(), Args, &C, false, getLoc(Loc), {},
2019+
cxxCtor, {});
20162020

20172021
assert(CGM.getCodeGenOpts().OptimizationLevel == 0 ||
20182022
ClassDecl->isDynamicClass() || Type == Ctor_Base ||

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1572,10 +1572,15 @@ RValue CIRGenFunction::emitCXXDestructorCall(GlobalDecl Dtor,
15721572
commonBuildCXXMemberOrOperatorCall(*this, DtorDecl, This, ImplicitParam,
15731573
ImplicitParamTy, CE, Args, nullptr);
15741574
assert((CE || Dtor.getDecl()) && "expected source location provider");
1575+
1576+
auto cxxDtor = cir::CXXDtorAttr::get(
1577+
&getMLIRContext(),
1578+
getContext().getRecordType(DtorDecl->getParent()).getAsString());
15751579
return emitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
15761580
ReturnValueSlot(), Args, nullptr, CE && CE == MustTailCall,
15771581
CE ? getLoc(CE->getExprLoc())
1578-
: getLoc(Dtor.getDecl()->getSourceRange()));
1582+
: getLoc(Dtor.getDecl()->getSourceRange()),
1583+
{}, {}, cxxDtor);
15791584
}
15801585

15811586
/// Emit a call to an operator new or operator delete function, as implicitly

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,9 @@ class CIRGenFunction : public CIRGenTypeCache {
18601860
const CallArgList &Args,
18611861
cir::CIRCallOpInterface *callOrTryCall, bool IsMustTail,
18621862
mlir::Location loc,
1863-
std::optional<const clang::CallExpr *> E = std::nullopt);
1863+
std::optional<const clang::CallExpr *> E = std::nullopt,
1864+
std::optional<cir::CXXCtorAttr> cxxCtor = std::nullopt,
1865+
std::optional<cir::CXXDtorAttr> cxxDtor = std::nullopt);
18641866
RValue emitCall(const CIRGenFunctionInfo &CallInfo,
18651867
const CIRGenCallee &Callee, ReturnValueSlot ReturnValue,
18661868
const CallArgList &Args,

clang/test/CIR/CodeGen/String.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ void test() {
6464
// CHECK-NEXT: cir.store{{.*}} %arg1, %1 : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
6565
// CHECK-NEXT: %2 = cir.load{{.*}} %0 : !cir.ptr<!cir.ptr<!rec_String>>, !cir.ptr<!rec_String>
6666
// CHECK-NEXT: %3 = cir.load{{.*}} %1 : !cir.ptr<!cir.ptr<!s8i>>, !cir.ptr<!s8i>
67-
// CHECK-NEXT: cir.call @_ZN6StringC2EPKc(%2, %3) : (!cir.ptr<!rec_String>, !cir.ptr<!s8i>) -> ()
67+
// CHECK-NEXT: cir.call @_ZN6StringC2EPKc(%2, %3) {cxx_ctor = #cir.cxx_ctor<"class String">} : (!cir.ptr<!rec_String>, !cir.ptr<!s8i>) -> ()
6868
// CHECK-NEXT: cir.return
6969

7070
// CHECK: cir.func dso_local @_Z4testv()
71-
// CHECK: cir.call @_ZN6StringC1Ev(%0) : (!cir.ptr<!rec_String>) -> ()
72-
// CHECK: cir.call @_ZN6StringC1Ei(%1, %3) : (!cir.ptr<!rec_String>, !s32i) -> ()
73-
// CHECK: cir.call @_ZN6StringC1EPKc(%2, %5) : (!cir.ptr<!rec_String>, !cir.ptr<!s8i>) -> ()
71+
// CHECK: cir.call @_ZN6StringC1Ev(%0) {cxx_ctor = #cir.cxx_ctor<"class String">} : (!cir.ptr<!rec_String>) -> ()
72+
// CHECK: cir.call @_ZN6StringC1Ei(%1, %3) {cxx_ctor = #cir.cxx_ctor<"class String">} : (!cir.ptr<!rec_String>, !s32i) -> ()
73+
// CHECK: cir.call @_ZN6StringC1EPKc(%2, %5) {cxx_ctor = #cir.cxx_ctor<"class String">} : (!cir.ptr<!rec_String>, !cir.ptr<!s8i>) -> ()

clang/test/CIR/CodeGen/agg-init-inherit.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void f1() {
1616
// CIR: cir.func dso_local @_Z2f1v()
1717
// CIR: %0 = cir.alloca !rec_B, !cir.ptr<!rec_B>, ["v", init]
1818
// CIR: %1 = cir.base_class_addr %0 : !cir.ptr<!rec_B> nonnull [0] -> !cir.ptr<!rec_A1>
19-
// CIR: cir.call @_ZN2A1C2Ev(%1) : (!cir.ptr<!rec_A1>) -> ()
19+
// CIR: cir.call @_ZN2A1C2Ev(%1) {cxx_ctor = #cir.cxx_ctor<"struct A1">} : (!cir.ptr<!rec_A1>) -> ()
2020
// CIR: cir.return
2121
// LLVM: define dso_local void @_Z2f1v()
2222
// LLVM: %1 = alloca %class.B, i64 1, align 1
@@ -35,9 +35,9 @@ void f2() {
3535
// CIR: cir.func dso_local @_Z2f2v()
3636
// CIR: %0 = cir.alloca !rec_C, !cir.ptr<!rec_C>, ["v", init]
3737
// CIR: %1 = cir.base_class_addr %0 : !cir.ptr<!rec_C> nonnull [0] -> !cir.ptr<!rec_A1>
38-
// CIR: cir.call @_ZN2A1C2Ev(%1) : (!cir.ptr<!rec_A1>) -> ()
38+
// CIR: cir.call @_ZN2A1C2Ev(%1) {cxx_ctor = #cir.cxx_ctor<"struct A1">} : (!cir.ptr<!rec_A1>) -> ()
3939
// CIR: %2 = cir.base_class_addr %0 : !cir.ptr<!rec_C> nonnull [0] -> !cir.ptr<!rec_A2>
40-
// CIR: cir.call @_ZN2A2C2Ev(%2) : (!cir.ptr<!rec_A2>) -> ()
40+
// CIR: cir.call @_ZN2A2C2Ev(%2) {cxx_ctor = #cir.cxx_ctor<"struct A2">} : (!cir.ptr<!rec_A2>) -> ()
4141
// CIR: cir.return
4242
// LLVM: define dso_local void @_Z2f2v()
4343
// LLVM: %1 = alloca %class.C, i64 1, align 1
@@ -58,8 +58,8 @@ void f3() {
5858
// CIR: cir.func dso_local @_Z2f3v()
5959
// CIR: %0 = cir.alloca !rec_D, !cir.ptr<!rec_D>, ["v", init]
6060
// CIR: %1 = cir.base_class_addr %0 : !cir.ptr<!rec_D> nonnull [0] -> !cir.ptr<!rec_A3>
61-
// CIR: cir.call @_ZN2A3C2Ev(%1) : (!cir.ptr<!rec_A3>) -> ()
62-
// CIR: cir.call @_ZN1DD1Ev(%0) : (!cir.ptr<!rec_D>) -> ()
61+
// CIR: cir.call @_ZN2A3C2Ev(%1) {cxx_ctor = #cir.cxx_ctor<"struct A3">} : (!cir.ptr<!rec_A3>) -> ()
62+
// CIR: cir.call @_ZN1DD1Ev(%0) {cxx_dtor = #cir.cxx_dtor<"class D">} : (!cir.ptr<!rec_D>) -> ()
6363
// CIR: cir.return
6464
// LLVM: define dso_local void @_Z2f3v()
6565
// LLVM: %1 = alloca %class.D, i64 1, align 1

clang/test/CIR/CodeGen/agg-init2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ void f() {
1616
// CHECK: cir.func dso_local @_Z1fv()
1717
// CHECK: %0 = cir.alloca !rec_Zero, !cir.ptr<!rec_Zero>, ["z0", init]
1818
// CHECK: %1 = cir.alloca !rec_Zero, !cir.ptr<!rec_Zero>, ["z1"]
19-
// CHECK: cir.call @_ZN4ZeroC1Ev(%0) : (!cir.ptr<!rec_Zero>) -> ()
19+
// CHECK: cir.call @_ZN4ZeroC1Ev(%0) {cxx_ctor = #cir.cxx_ctor<"struct Zero">} : (!cir.ptr<!rec_Zero>) -> ()
2020
// CHECK: cir.return

clang/test/CIR/CodeGen/array-init-destroy.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ void x() {
2424

2525
// BEFORE: cir.array.ctor(%[[ArrayAddr]] : !cir.ptr<!cir.array<!rec_xpto x 2>>) {
2626
// BEFORE: ^bb0(%arg0: !cir.ptr<!rec_xpto>
27-
// BEFORE: cir.call @_ZN4xptoC1Ev(%arg0) : (!cir.ptr<!rec_xpto>) -> ()
27+
// BEFORE: cir.call @_ZN4xptoC1Ev(%arg0) {cxx_ctor = #cir.cxx_ctor<"class xpto">} : (!cir.ptr<!rec_xpto>) -> ()
2828
// BEFORE: cir.yield
2929
// BEFORE: }
3030

3131
// BEFORE: cir.array.dtor(%[[ArrayAddr]] : !cir.ptr<!cir.array<!rec_xpto x 2>>) {
3232
// BEFORE: ^bb0(%arg0: !cir.ptr<!rec_xpto>
33-
// BEFORE: cir.call @_ZN4xptoD1Ev(%arg0) : (!cir.ptr<!rec_xpto>) -> ()
33+
// BEFORE: cir.call @_ZN4xptoD1Ev(%arg0) {cxx_dtor = #cir.cxx_dtor<"class xpto">} : (!cir.ptr<!rec_xpto>) -> ()
3434
// BEFORE: cir.yield
3535
// BEFORE: }
3636

@@ -44,7 +44,7 @@ void x() {
4444
// AFTER: cir.do {
4545
// AFTER: %[[ArrayElt:.*]] = cir.load %[[TmpIdx]] : !cir.ptr<!cir.ptr<!rec_xpto>>, !cir.ptr<!rec_xpto>
4646
// AFTER: %[[ConstOne:.*]] = cir.const #cir.int<1> : !u64i
47-
// AFTER: cir.call @_ZN4xptoC1Ev(%[[ArrayElt]]) : (!cir.ptr<!rec_xpto>) -> ()
47+
// AFTER: cir.call @_ZN4xptoC1Ev(%[[ArrayElt]]) {cxx_ctor = #cir.cxx_ctor<"class xpto">} : (!cir.ptr<!rec_xpto>) -> ()
4848
// AFTER: %[[NextElt:.*]] = cir.ptr_stride(%[[ArrayElt]] : !cir.ptr<!rec_xpto>, %[[ConstOne]] : !u64i), !cir.ptr<!rec_xpto>
4949
// AFTER: cir.store %[[NextElt]], %[[TmpIdx]] : !cir.ptr<!rec_xpto>, !cir.ptr<!cir.ptr<!rec_xpto>>
5050
// AFTER: cir.yield
@@ -55,7 +55,7 @@ void x() {
5555
// AFTER: }
5656

5757
// AFTER: cir.do {
58-
// AFTER: cir.call @_ZN4xptoD1Ev({{.*}}) : (!cir.ptr<!rec_xpto>) -> ()
58+
// AFTER: cir.call @_ZN4xptoD1Ev({{.*}}) {cxx_dtor = #cir.cxx_dtor<"class xpto">} : (!cir.ptr<!rec_xpto>) -> ()
5959
// AFTER: } while {
6060
// AFTER: }
6161

clang/test/CIR/CodeGen/array-new-init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void t_new_constant_size_constructor() {
2525
// BEFORE: %[[OBJ_ARRAY_PTR:.*]] = cir.cast(bitcast, %[[OBJ_ELEM_PTR]] : !cir.ptr<!rec_E>), !cir.ptr<!cir.array<!rec_E x 3>>
2626
// BEFORE: cir.array.ctor(%[[OBJ_ARRAY_PTR]] : !cir.ptr<!cir.array<!rec_E x 3>>) {
2727
// BEFORE: ^bb0(%arg0: !cir.ptr<!rec_E>
28-
// BEFORE: cir.call @_ZN1EC1Ev(%arg0) : (!cir.ptr<!rec_E>) -> ()
28+
// BEFORE: cir.call @_ZN1EC1Ev(%arg0) {cxx_ctor = #cir.cxx_ctor<"class E">} : (!cir.ptr<!rec_E>) -> ()
2929
// BEFORE: cir.yield
3030
// BEFORE: }
3131

@@ -49,7 +49,7 @@ void t_new_constant_size_constructor() {
4949
// AFTER: cir.do {
5050
// AFTER: %[[CUR_ELEM_PTR:.*]] = cir.load %[[CUR_ELEM_ALLOCA]] : !cir.ptr<!cir.ptr<!rec_E>>, !cir.ptr<!rec_E>
5151
// AFTER: %[[OFFSET:.*]] = cir.const #cir.int<1> : !u64i
52-
// AFTER: cir.call @_ZN1EC1Ev(%[[CUR_ELEM_PTR]]) : (!cir.ptr<!rec_E>) -> ()
52+
// AFTER: cir.call @_ZN1EC1Ev(%[[CUR_ELEM_PTR]]) {cxx_ctor = #cir.cxx_ctor<"class E">} : (!cir.ptr<!rec_E>) -> ()
5353
// AFTER: %[[NEXT_PTR:.*]] = cir.ptr_stride(%[[CUR_ELEM_PTR]] : !cir.ptr<!rec_E>, %[[OFFSET]] : !u64i), !cir.ptr<!rec_E>
5454
// AFTER: cir.store{{.*}} %[[NEXT_PTR]], %[[CUR_ELEM_ALLOCA]] : !cir.ptr<!rec_E>, !cir.ptr<!cir.ptr<!rec_E>>
5555
// AFTER: cir.yield

0 commit comments

Comments
 (0)