[llvm-branch-commits] [clang] [CIR][CodeGen][NFC] Share the Itanium __vmi_class_type_info flags computation (PR #227256)
Henrich Lauko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 29 04:22:33 PDT 2026
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/227256
>From f439dac3490d91517e686bf26113a2ad8cfea27d Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
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`.
---
.../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 a4acd242eee1a..397d8f43895e6 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
@@ -850,61 +831,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.
@@ -1213,7 +1139,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:
@@ -1280,9 +1206,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 f97871a3a2523..228a2a6e689da 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);
@@ -4378,64 +4360,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.
@@ -4447,7 +4371,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:
@@ -4514,9 +4438,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();
More information about the llvm-branch-commits
mailing list