From f78d6caadc60b58a6cf390efc2b3d2da7a21caef Mon Sep 17 00:00:00 2001 From: Morris Hafner Date: Mon, 14 Jul 2025 19:02:00 +0200 Subject: [CIR] Add Minimal Destructor Definition Support (#144719) This patch upstreams support for writing inline and out of line C++ destructor definitions. Calling a destructor implcitly or explicitly is left for a future patch. Because of that restriction complete destructors (D2 in Itanium mangling) do not call into the base (D1) destructors yet but simply behave like a base destructor. Deleting (D0) destructor support is not part of this patch. Destructor aliases aren't supported, either. Because of this compilation with -mno-constructor-aliases may be required to avoid running into NYI errors. --- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp') diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 8b2883b..3502705 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1111,14 +1111,14 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) { } cir::GlobalLinkageKind CIRGenModule::getFunctionLinkage(GlobalDecl gd) { - const auto *fd = cast(gd.getDecl()); + const auto *d = cast(gd.getDecl()); - GVALinkage linkage = astContext.GetGVALinkageForFunction(fd); + GVALinkage linkage = astContext.GetGVALinkageForFunction(d); - if (isa(fd)) - errorNYI(fd->getSourceRange(), "getFunctionLinkage: CXXDestructorDecl"); + if (const auto *dtor = dyn_cast(d)) + return getCXXABI().getCXXDestructorLinkage(linkage, dtor, gd.getDtorType()); - return getCIRLinkageForDeclarator(fd, linkage, /*IsConstantVariable=*/false); + return getCIRLinkageForDeclarator(d, linkage, /*isConstantVariable=*/false); } static cir::GlobalOp @@ -1274,6 +1274,9 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { case Decl::CXXConstructor: getCXXABI().emitCXXConstructors(cast(decl)); break; + case Decl::CXXDestructor: + getCXXABI().emitCXXDestructors(cast(decl)); + break; // C++ Decls case Decl::LinkageSpec: @@ -1335,6 +1338,17 @@ cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd, funcType = convertType(fd->getType()); } + // Devirtualized destructor calls may come through here instead of via + // getAddrOfCXXStructor. Make sure we use the MS ABI base destructor instead + // of the complete destructor when necessary. + if (const auto *dd = dyn_cast(gd.getDecl())) { + if (getTarget().getCXXABI().isMicrosoft() && + gd.getDtorType() == Dtor_Complete && + dd->getParent()->getNumVBases() == 0) + errorNYI(dd->getSourceRange(), + "getAddrOfFunction: MS ABI complete destructor"); + } + StringRef mangledName = getMangledName(gd); cir::FuncOp func = getOrCreateCIRFunction(mangledName, funcType, gd, forVTable, dontDefer, @@ -1729,7 +1743,9 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction( // All MSVC dtors other than the base dtor are linkonce_odr and delegate to // each other bottoming out wiht the base dtor. Therefore we emit non-base // dtors on usage, even if there is no dtor definition in the TU. - if (isa_and_nonnull(d)) + if (isa_and_nonnull(d) && + getCXXABI().useThunkForDtorVariant(cast(d), + gd.getDtorType())) errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: dtor"); // This is the first use or definition of a mangled name. If there is a -- cgit v1.1