@@ -130,13 +130,11 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
130130 const CXXMethodDecl *calleeDecl =
131131 devirtualizedMethod ? devirtualizedMethod : md;
132132 const CIRGenFunctionInfo *fInfo = nullptr ;
133- if (isa<CXXDestructorDecl>(calleeDecl)) {
134- cgm.errorNYI (ce->getSourceRange (),
135- " emitCXXMemberOrOperatorMemberCallExpr: destructor call" );
136- return RValue::get (nullptr );
137- }
138-
139- fInfo = &cgm.getTypes ().arrangeCXXMethodDeclaration (calleeDecl);
133+ if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl))
134+ fInfo = &cgm.getTypes ().arrangeCXXStructorDeclaration (
135+ GlobalDecl (dtor, Dtor_Complete));
136+ else
137+ fInfo = &cgm.getTypes ().arrangeCXXMethodDeclaration (calleeDecl);
140138
141139 cir::FuncType ty = cgm.getTypes ().getFunctionType (*fInfo );
142140
@@ -151,9 +149,34 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
151149 // because then we know what the type is.
152150 bool useVirtualCall = canUseVirtualCall && !devirtualizedMethod;
153151
154- if (isa<CXXDestructorDecl>(calleeDecl)) {
155- cgm.errorNYI (ce->getSourceRange (),
156- " emitCXXMemberOrOperatorMemberCallExpr: destructor call" );
152+ if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) {
153+ assert (ce->arg_begin () == ce->arg_end () &&
154+ " Destructor shouldn't have explicit parameters" );
155+ assert (returnValue.isNull () && " Destructor shouldn't have return value" );
156+ if (useVirtualCall) {
157+ cgm.getCXXABI ().emitVirtualDestructorCall (*this , dtor, Dtor_Complete,
158+ thisPtr.getAddress (),
159+ cast<CXXMemberCallExpr>(ce));
160+ } else {
161+ GlobalDecl globalDecl (dtor, Dtor_Complete);
162+ CIRGenCallee callee;
163+ assert (!cir::MissingFeatures::appleKext ());
164+ if (!devirtualizedMethod) {
165+ callee = CIRGenCallee::forDirect (
166+ cgm.getAddrOfCXXStructor (globalDecl, fInfo , ty), globalDecl);
167+ } else {
168+ cgm.errorNYI (ce->getSourceRange (), " devirtualized destructor call" );
169+ return RValue::get (nullptr );
170+ }
171+
172+ QualType thisTy =
173+ isArrow ? base->getType ()->getPointeeType () : base->getType ();
174+ // CIRGen does not pass CallOrInvoke here (different from OG LLVM codegen)
175+ // because in practice it always null even in OG.
176+ emitCXXDestructorCall (globalDecl, callee, thisPtr.getPointer (), thisTy,
177+ /* implicitParam=*/ nullptr ,
178+ /* implicitParamTy=*/ QualType (), ce);
179+ }
157180 return RValue::get (nullptr );
158181 }
159182
0 commit comments