https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/227257
>From f4f62f30f4efdde293c7df7c26f8861f40a48716 Mon Sep 17 00:00:00 2001 From: Henrich Lauko <[email protected]> Date: Tue, 29 Sep 2026 09:55:33 +0000 Subject: [PATCH] [CIR][CodeGen][NFC] Share canUseSingleInheritance Deduplicates `canUseSingleInheritance` between CIR and classic CodeGen into `ItaniumCXXABIUtils.h`. Assisted-by: Claude Code (Claude Fable 5.1). --- .../clang/CodeGenUtils/ItaniumCXXABIUtils.h | 5 +++ clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 30 ++--------------- clang/lib/CodeGen/ItaniumCXXABI.cpp | 32 ++----------------- clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp | 22 +++++++++++++ 4 files changed, 31 insertions(+), 58 deletions(-) diff --git a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h index 59b94c9bb08c3..9d6a20ef82ab3 100644 --- a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h +++ b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h @@ -62,6 +62,11 @@ enum BaseClassTypeInfoFlags { BCTI_Public = 0x2 }; +/// Return whether the given record decl has a "single, public, non-virtual +/// base at offset zero (i.e. the derived class is dynamic iff the base is)", +/// according to Itanium C++ ABI, 2.95p6b. +bool canUseSingleInheritance(const CXXRecordDecl *RD); + /// Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7]. CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, const CXXRecordDecl *Dst); diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 763ed026f8714..25526f0668f00 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -835,32 +835,6 @@ static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) { return false; } -// Return whether the given record decl has a "single, -// public, non-virtual base at offset zero (i.e. the derived class is dynamic -// iff the base is)", according to Itanium C++ ABI, 2.95p6b. -// TODO(cir): this can unified with LLVM codegen -static bool canUseSingleInheritance(const CXXRecordDecl *rd) { - // Check the number of bases. - if (rd->getNumBases() != 1) - return false; - - // Get the base. - CXXRecordDecl::base_class_const_iterator base = rd->bases_begin(); - - // Check that the base is not virtual. - if (base->isVirtual()) - return false; - - // Check that the base is public. - if (base->getAccessSpecifier() != AS_public) - return false; - - // Check that the class is dynamic iff the base is. - auto *baseDecl = base->getType()->castAsCXXRecordDecl(); - return baseDecl->isEmpty() || - baseDecl->isDynamicClass() == rd->isDynamicClass(); -} - const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) { // abi::__class_type_info. static const char *const classTypeInfo = @@ -929,7 +903,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) { return classTypeInfo; } - if (canUseSingleInheritance(rd)) { + if (CodeGenUtils::canUseSingleInheritance(rd)) { return siClassTypeInfo; } @@ -1425,7 +1399,7 @@ mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo( break; } - if (canUseSingleInheritance(rd)) { + if (CodeGenUtils::canUseSingleInheritance(rd)) { buildSIClassTypeInfo(loc, rd); } else { buildVMIClassTypeInfo(loc, rd); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 8e9aaa1313528..c851385822291 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3822,34 +3822,6 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, return false; } -// CanUseSingleInheritance - Return whether the given record decl has a "single, -// public, non-virtual base at offset zero (i.e. the derived class is dynamic -// iff the base is)", according to Itanium C++ ABI, 2.95p6b. -static bool CanUseSingleInheritance(const CXXRecordDecl *RD) { - // Check the number of bases. - if (RD->getNumBases() != 1) - return false; - - // Get the base. - CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(); - - // Check that the base is not virtual. - if (Base->isVirtual()) - return false; - - // Check that the base is public. - if (Base->getAccessSpecifier() != AS_public) - return false; - - // Check that the class is dynamic iff the base is. - auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); - if (!BaseDecl->isEmpty() && - BaseDecl->isDynamicClass() != RD->isDynamicClass()) - return false; - - return true; -} - void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty, llvm::Constant *StorageAddress) { // abi::__class_type_info. @@ -3926,7 +3898,7 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty, if (!RD->hasDefinition() || !RD->getNumBases()) { VTableName = ClassTypeInfo; - } else if (CanUseSingleInheritance(RD)) { + } else if (CodeGenUtils::canUseSingleInheritance(RD)) { VTableName = SIClassTypeInfo; } else { VTableName = VMIClassTypeInfo; @@ -4244,7 +4216,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( break; } - if (CanUseSingleInheritance(RD)) + if (CodeGenUtils::canUseSingleInheritance(RD)) BuildSIClassTypeInfo(RD); else BuildVMIClassTypeInfo(RD); diff --git a/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp b/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp index a1ab26cfc17b0..2f22ab69d4c5a 100644 --- a/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp +++ b/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp @@ -61,6 +61,28 @@ CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, return Offset; } +bool canUseSingleInheritance(const CXXRecordDecl *RD) { + // Check the number of bases. + if (RD->getNumBases() != 1) + return false; + + // Get the base. + CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(); + + // Check that the base is not virtual. + if (Base->isVirtual()) + return false; + + // Check that the base is public. + if (Base->getAccessSpecifier() != AS_public) + return false; + + // Check that the class is dynamic iff the base is. + auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); + return BaseDecl->isEmpty() || + BaseDecl->isDynamicClass() == RD->isDynamicClass(); +} + namespace { /// Contains virtual and non-virtual bases seen when traversing a class /// hierarchy. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
