https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/227256
>From 65a6eb756f177e16ba41f6d48e2fb9044bb197b2 Mon Sep 17 00:00:00 2001 From: Henrich Lauko <[email protected]> Date: Tue, 29 Sep 2026 09:55:27 +0000 Subject: [PATCH] [CIR][CodeGen][NFC] Share the Itanium __vmi_class_type_info flags computation Deduplicates the `__vmi_class_type_info` and `__base_class_type_info` flags and `computeVMIClassTypeInfoFlags` between CIR and classic CodeGen into `ItaniumCXXABIUtils.h`. Assisted-by: Claude Code (Claude Fable 5.1). --- .../clang/CodeGenUtils/ItaniumCXXABIUtils.h | 21 +++++ clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 80 +----------------- clang/lib/CodeGen/ItaniumCXXABI.cpp | 82 +------------------ clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp | 54 ++++++++++++ 4 files changed, 81 insertions(+), 156 deletions(-) diff --git a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h index fb125e796aa19..59b94c9bb08c3 100644 --- a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h +++ b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h @@ -44,10 +44,31 @@ enum PointerTypeInfoFlags { PTI_Noexcept = 0x40, }; +/// Flags for abi::__vmi_class_type_info. +enum VMIClassTypeInfoFlags { + /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance. + VMI_NonDiamondRepeat = 0x1, + + /// VMI_DiamondShaped - Class is diamond shaped. + VMI_DiamondShaped = 0x2 +}; + +/// Flags for abi::__base_class_type_info. +enum BaseClassTypeInfoFlags { + /// BCTI_Virtual - Base class is virtual. + BCTI_Virtual = 0x1, + + /// BCTI_Public - Base class is public. + BCTI_Public = 0x2 +}; + /// 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); +/// Compute the value of the flags member in abi::__vmi_class_type_info. +unsigned computeVMIClassTypeInfoFlags(const CXXRecordDecl *RD); + /// Returns whether the given type contains an incomplete class type. This is /// true if /// diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index b8d329ab06bb0..763ed026f8714 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -638,27 +638,8 @@ class CIRGenItaniumRTTIBuilder { }; } // namespace -// TODO(cir): Will be removed after sharing them with the classical codegen namespace { -// VMI type info flags. -enum { - /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance. - VMI_NonDiamondRepeat = 0x1, - - /// VMI_DiamondShaped - Class is diamond shaped. - VMI_DiamondShaped = 0x2 -}; - -// Base class type info flags. -enum { - /// BCTI_Virtual - Base class is virtual. - BCTI_Virtual = 0x1, - - /// BCTI_Public - Base class is public. - BCTI_Public = 0x2 -}; - /// Given a builtin type, returns whether the type /// info for that type is defined in the standard library. /// TODO(cir): this can unified with LLVM codegen @@ -854,61 +835,6 @@ static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) { return false; } -/// Contains virtual and non-virtual bases seen when traversing a class -/// hierarchy. -struct SeenBases { - llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases; - llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases; -}; - -/// Compute the value of the flags member in abi::__vmi_class_type_info. -/// -static unsigned computeVmiClassTypeInfoFlags(const CXXBaseSpecifier *base, - SeenBases &bases) { - - unsigned flags = 0; - auto *baseDecl = base->getType()->castAsCXXRecordDecl(); - - if (base->isVirtual()) { - // Mark the virtual base as seen. - if (!bases.virtualBases.insert(baseDecl).second) { - // If this virtual base has been seen before, then the class is diamond - // shaped. - flags |= VMI_DiamondShaped; - } else { - if (bases.nonVirtualBases.count(baseDecl)) - flags |= VMI_NonDiamondRepeat; - } - } else { - // Mark the non-virtual base as seen. - if (!bases.nonVirtualBases.insert(baseDecl).second) { - // If this non-virtual base has been seen before, then the class has non- - // diamond shaped repeated inheritance. - flags |= VMI_NonDiamondRepeat; - } else { - if (bases.virtualBases.count(baseDecl)) - flags |= VMI_NonDiamondRepeat; - } - } - - // Walk all bases. - for (const auto &bs : baseDecl->bases()) - flags |= computeVmiClassTypeInfoFlags(&bs, bases); - - return flags; -} - -static unsigned computeVmiClassTypeInfoFlags(const CXXRecordDecl *rd) { - unsigned flags = 0; - SeenBases bases; - - // Walk all bases. - for (const auto &bs : rd->bases()) - flags |= computeVmiClassTypeInfoFlags(&bs, bases); - - return flags; -} - // 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. @@ -1217,7 +1143,7 @@ void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc, // __flags is a word with flags describing details about the class // structure, which may be referenced by using the __flags_masks // enumeration. These flags refer to both direct and indirect bases. - unsigned flags = computeVmiClassTypeInfoFlags(rd); + unsigned flags = CodeGenUtils::computeVMIClassTypeInfoFlags(rd); fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags)); // Itanium C++ ABI 2.9.5p6c: @@ -1284,9 +1210,9 @@ void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc, // The low-order byte of __offset_flags contains flags, as given by the // masks from the enumeration __offset_flags_masks. if (base.isVirtual()) - offsetFlags |= BCTI_Virtual; + offsetFlags |= CodeGenUtils::BCTI_Virtual; if (base.getAccessSpecifier() == AS_public) - offsetFlags |= BCTI_Public; + offsetFlags |= CodeGenUtils::BCTI_Public; fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags)); } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5fe80e16f68c8..8e9aaa1313528 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3545,24 +3545,6 @@ class ItaniumRTTIBuilder { ItaniumRTTIBuilder(const ItaniumCXXABI &ABI) : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {} - // VMI type info flags. - enum { - /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance. - VMI_NonDiamondRepeat = 0x1, - - /// VMI_DiamondShaped - Class is diamond shaped. - VMI_DiamondShaped = 0x2 - }; - - // Base class type info flags. - enum { - /// BCTI_Virtual - Base class is virtual. - BCTI_Virtual = 0x1, - - /// BCTI_Public - Base class is public. - BCTI_Public = 0x2 - }; - /// BuildTypeInfo - Build the RTTI type info struct for the given type, or /// link to an existing RTTI descriptor if one already exists. llvm::Constant *BuildTypeInfo(QualType Ty); @@ -4381,64 +4363,6 @@ void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) { Fields.push_back(BaseTypeInfo); } -namespace { - /// SeenBases - Contains virtual and non-virtual bases seen when traversing - /// a class hierarchy. - struct SeenBases { - llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases; - llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases; - }; -} - -/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in -/// abi::__vmi_class_type_info. -/// -static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, - SeenBases &Bases) { - - unsigned Flags = 0; - - auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); - if (Base->isVirtual()) { - // Mark the virtual base as seen. - if (!Bases.VirtualBases.insert(BaseDecl).second) { - // If this virtual base has been seen before, then the class is diamond - // shaped. - Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped; - } else { - if (Bases.NonVirtualBases.count(BaseDecl)) - Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat; - } - } else { - // Mark the non-virtual base as seen. - if (!Bases.NonVirtualBases.insert(BaseDecl).second) { - // If this non-virtual base has been seen before, then the class has non- - // diamond shaped repeated inheritance. - Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat; - } else { - if (Bases.VirtualBases.count(BaseDecl)) - Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat; - } - } - - // Walk all bases. - for (const auto &I : BaseDecl->bases()) - Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases); - - return Flags; -} - -static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) { - unsigned Flags = 0; - SeenBases Bases; - - // Walk all bases. - for (const auto &I : RD->bases()) - Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases); - - return Flags; -} - /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for /// classes with bases that do not satisfy the abi::__si_class_type_info /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c. @@ -4450,7 +4374,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // __flags is a word with flags describing details about the class // structure, which may be referenced by using the __flags_masks // enumeration. These flags refer to both direct and indirect bases. - unsigned Flags = ComputeVMIClassTypeInfoFlags(RD); + unsigned Flags = CodeGenUtils::computeVMIClassTypeInfoFlags(RD); Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags)); // Itanium C++ ABI 2.9.5p6c: @@ -4517,9 +4441,9 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // The low-order byte of __offset_flags contains flags, as given by the // masks from the enumeration __offset_flags_masks. if (Base.isVirtual()) - OffsetFlags |= BCTI_Virtual; + OffsetFlags |= CodeGenUtils::BCTI_Virtual; if (Base.getAccessSpecifier() == AS_public) - OffsetFlags |= BCTI_Public; + OffsetFlags |= CodeGenUtils::BCTI_Public; Fields.push_back(llvm::ConstantInt::getSigned(OffsetFlagsLTy, OffsetFlags)); } diff --git a/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp b/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp index 1073be5a76acf..a1ab26cfc17b0 100644 --- a/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp +++ b/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp @@ -61,6 +61,60 @@ CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, return Offset; } +namespace { +/// Contains virtual and non-virtual bases seen when traversing a class +/// hierarchy. +struct SeenBases { + llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases; + llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases; +}; +} // namespace + +static unsigned computeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, + SeenBases &Bases) { + unsigned Flags = 0; + + auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); + if (Base->isVirtual()) { + // Mark the virtual base as seen. + if (!Bases.VirtualBases.insert(BaseDecl).second) { + // If this virtual base has been seen before, then the class is diamond + // shaped. + Flags |= VMI_DiamondShaped; + } else { + if (Bases.NonVirtualBases.count(BaseDecl)) + Flags |= VMI_NonDiamondRepeat; + } + } else { + // Mark the non-virtual base as seen. + if (!Bases.NonVirtualBases.insert(BaseDecl).second) { + // If this non-virtual base has been seen before, then the class has non- + // diamond shaped repeated inheritance. + Flags |= VMI_NonDiamondRepeat; + } else { + if (Bases.VirtualBases.count(BaseDecl)) + Flags |= VMI_NonDiamondRepeat; + } + } + + // Walk all bases. + for (const auto &I : BaseDecl->bases()) + Flags |= computeVMIClassTypeInfoFlags(&I, Bases); + + return Flags; +} + +unsigned computeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) { + unsigned Flags = 0; + SeenBases Bases; + + // Walk all bases. + for (const auto &I : RD->bases()) + Flags |= computeVMIClassTypeInfoFlags(&I, Bases); + + return Flags; +} + /// Returns whether the given record type is incomplete. static bool isIncompleteClassType(const RecordType *RecordTy) { return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
